aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Peryt <sebastian.peryt@intel.com>2018-04-19 17:08:02 +0200
committerSebastian Peryt <speryt@gcc.gnu.org>2018-04-19 17:08:02 +0200
commit37d51c754a8c0c2b3216b5574cfcf3e12d786658 (patch)
tree7290c8661b7d9588a63f1c05bc4c759df8cbcdc6
parentca98e4c5d0e87b5305ab30591509ffc64300abd4 (diff)
downloadgcc-37d51c754a8c0c2b3216b5574cfcf3e12d786658.zip
gcc-37d51c754a8c0c2b3216b5574cfcf3e12d786658.tar.gz
gcc-37d51c754a8c0c2b3216b5574cfcf3e12d786658.tar.bz2
i386-common.c (OPTION_MASK_ISA_MOVDIRI_SET, [...]): New defines.
2018-04-19 Sebastian Peryt <sebastian.peryt@intel.com> gcc/ * common/config/i386/i386-common.c (OPTION_MASK_ISA_MOVDIRI_SET, OPTION_MASK_ISA_MOVDIR64B_SET, OPTION_MASK_ISA_MOVDIRI_UNSET, OPTION_MASK_ISA_MOVDIR64B_UNSET): New defines. (ix86_handle_option): Handle -mmovdiri and -mmovdir64b. * config.gcc (movdirintrin.h): New header. * config/i386/cpuid.h (bit_MOVDIRI, bit_MOVDIR64B): New bits. * config/i386/driver-i386.c (host_detect_local_cpu): Detect -mmovdiri and -mmvodir64b. * config/i386/i386-builtin-types.def ((VOID, PUNSIGNED, UNSIGNED), (VOID, PVOID, PCVOID)): New function types. * config/i386/i386-builtin.def (__builtin_ia32_directstoreu_u32, __builtin_ia32_directstoreu_u64, __builtin_ia32_movdir64b): New builtins. * config/i386/i386-c.c (__MOVDIRI__, __MOVDIR64B__): New. * config/i386/i386.c (ix86_target_string): Added -mmovdir64b and -mmovdiri. (ix86_valid_target_attribute_inner_p): Ditto. (ix86_expand_special_args_builtin): Added VOID_FTYPE_PUNSIGNED_UNSIGNED and VOID_FTYPE_PUNSIGNED_UNSIGNED. (ix86_expand_builtin): Expand IX86_BUILTIN_MOVDIR64B. * config/i386/i386.h (TARGET_MOVDIRI, TARGET_MOVDIRI_P, TARGET_MOVDIR64B, TARGET_MOVDIR64B_P): New. * config/i386/i386.md (UNSPECV_MOVDIRI, UNSPECV_MOVDIR64B): New. (movdiri<mode>, movdir64b_<mode>): New. * config/i386/i386.opt: Add -mmovdiri and -mmovdir64b. * config/i386/immintrin.h: Include movdirintrin.h. * config/i386/movdirintrin.h: New file. * doc/invoke.texi: Added -mmovdiri and -mmovdir64b. gcc/testsuite/ * gcc.target/i386/movdir-1.c: New test. From-SVN: r259495
-rw-r--r--gcc/ChangeLog33
-rw-r--r--gcc/common/config/i386/i386-common.c30
-rw-r--r--gcc/config.gcc4
-rw-r--r--gcc/config/i386/cpuid.h2
-rw-r--r--gcc/config/i386/driver-i386.c7
-rw-r--r--gcc/config/i386/i386-builtin-types.def2
-rw-r--r--gcc/config/i386/i386-builtin.def5
-rw-r--r--gcc/config/i386/i386-c.c4
-rw-r--r--gcc/config/i386/i386.c33
-rw-r--r--gcc/config/i386/i386.h4
-rw-r--r--gcc/config/i386/i386.md18
-rw-r--r--gcc/config/i386/i386.opt8
-rw-r--r--gcc/config/i386/immintrin.h2
-rw-r--r--gcc/config/i386/movdirintrin.h74
-rw-r--r--gcc/doc/invoke.texi12
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/i386/movdir-1.c30
17 files changed, 264 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3331e6d..5ea65e7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,36 @@
+2018-04-19 Sebastian Peryt <sebastian.peryt@intel.com>
+
+ * common/config/i386/i386-common.c
+ (OPTION_MASK_ISA_MOVDIRI_SET, OPTION_MASK_ISA_MOVDIR64B_SET,
+ OPTION_MASK_ISA_MOVDIRI_UNSET,
+ OPTION_MASK_ISA_MOVDIR64B_UNSET): New defines.
+ (ix86_handle_option): Handle -mmovdiri and -mmovdir64b.
+ * config.gcc (movdirintrin.h): New header.
+ * config/i386/cpuid.h (bit_MOVDIRI,
+ bit_MOVDIR64B): New bits.
+ * config/i386/driver-i386.c (host_detect_local_cpu): Detect -mmovdiri
+ and -mmvodir64b.
+ * config/i386/i386-builtin-types.def ((VOID, PUNSIGNED, UNSIGNED),
+ (VOID, PVOID, PCVOID)): New function types.
+ * config/i386/i386-builtin.def (__builtin_ia32_directstoreu_u32,
+ __builtin_ia32_directstoreu_u64,
+ __builtin_ia32_movdir64b): New builtins.
+ * config/i386/i386-c.c (__MOVDIRI__, __MOVDIR64B__): New.
+ * config/i386/i386.c (ix86_target_string): Added -mmovdir64b
+ and -mmovdiri.
+ (ix86_valid_target_attribute_inner_p): Ditto.
+ (ix86_expand_special_args_builtin): Added VOID_FTYPE_PUNSIGNED_UNSIGNED
+ and VOID_FTYPE_PUNSIGNED_UNSIGNED.
+ (ix86_expand_builtin): Expand IX86_BUILTIN_MOVDIR64B.
+ * config/i386/i386.h (TARGET_MOVDIRI, TARGET_MOVDIRI_P,
+ TARGET_MOVDIR64B, TARGET_MOVDIR64B_P): New.
+ * config/i386/i386.md (UNSPECV_MOVDIRI, UNSPECV_MOVDIR64B): New.
+ (movdiri<mode>, movdir64b_<mode>): New.
+ * config/i386/i386.opt: Add -mmovdiri and -mmovdir64b.
+ * config/i386/immintrin.h: Include movdirintrin.h.
+ * config/i386/movdirintrin.h: New file.
+ * doc/invoke.texi: Added -mmovdiri and -mmovdir64b.
+
2018-04-19 Richard Biener <rguenther@suse.de>
PR middle-end/85455
diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c
index 7e49289..0bb2783 100644
--- a/gcc/common/config/i386/i386-common.c
+++ b/gcc/common/config/i386/i386-common.c
@@ -151,6 +151,8 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA_SHSTK_SET OPTION_MASK_ISA_SHSTK
#define OPTION_MASK_ISA_VAES_SET OPTION_MASK_ISA_VAES
#define OPTION_MASK_ISA_VPCLMULQDQ_SET OPTION_MASK_ISA_VPCLMULQDQ
+#define OPTION_MASK_ISA_MOVDIRI_SET OPTION_MASK_ISA_MOVDIRI
+#define OPTION_MASK_ISA_MOVDIR64B_SET OPTION_MASK_ISA_MOVDIR64B
/* Define a set of ISAs which aren't available when a given ISA is
disabled. MMX and SSE ISAs are handled separately. */
@@ -226,6 +228,8 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA_SHSTK_UNSET OPTION_MASK_ISA_SHSTK
#define OPTION_MASK_ISA_VAES_UNSET OPTION_MASK_ISA_VAES
#define OPTION_MASK_ISA_VPCLMULQDQ_UNSET OPTION_MASK_ISA_VPCLMULQDQ
+#define OPTION_MASK_ISA_MOVDIRI_UNSET OPTION_MASK_ISA_MOVDIRI
+#define OPTION_MASK_ISA_MOVDIR64B_UNSET OPTION_MASK_ISA_MOVDIR64B
/* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same
as -mno-sse4.1. */
@@ -596,6 +600,32 @@ ix86_handle_option (struct gcc_options *opts,
}
return true;
+ case OPT_mmovdiri:
+ if (value)
+ {
+ opts->x_ix86_isa_flags |= OPTION_MASK_ISA_MOVDIRI_SET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVDIRI_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_MOVDIRI_UNSET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVDIRI_UNSET;
+ }
+ return true;
+
+ case OPT_mmovdir64b:
+ if (value)
+ {
+ opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA_MOVDIR64B_SET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA_MOVDIR64B_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA_MOVDIR64B_UNSET;
+ opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA_MOVDIR64B_UNSET;
+ }
+ return true;
+
case OPT_mavx5124fmaps:
if (value)
{
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 9a93f88..e58494c 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -383,7 +383,7 @@ i[34567]86-*-*)
avx512vbmi2vlintrin.h avx512vnniintrin.h
avx512vnnivlintrin.h vaesintrin.h vpclmulqdqintrin.h
avx512vpopcntdqvlintrin.h avx512bitalgintrin.h
- pconfigintrin.h wbnoinvdintrin.h"
+ pconfigintrin.h wbnoinvdintrin.h movdirintrin.h"
;;
x86_64-*-*)
cpu_type=i386
@@ -412,7 +412,7 @@ x86_64-*-*)
avx512vbmi2vlintrin.h avx512vnniintrin.h
avx512vnnivlintrin.h vaesintrin.h vpclmulqdqintrin.h
avx512vpopcntdqvlintrin.h avx512bitalgintrin.h
- pconfigintrin.h wbnoinvdintrin.h"
+ pconfigintrin.h wbnoinvdintrin.h movdirintrin.h"
;;
ia64-*-*)
extra_headers=ia64intrin.h
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index 4096a0b..a26c5e4 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -107,6 +107,8 @@
#define bit_AVX512BITALG (1 << 12)
#define bit_AVX512VPOPCNTDQ (1 << 14)
#define bit_RDPID (1 << 22)
+#define bit_MOVDIRI (1 << 27)
+#define bit_MOVDIR64B (1 << 28)
/* %edx */
#define bit_AVX5124VNNIW (1 << 2)
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index 4f59854..19db252 100644
--- a/gcc/config/i386/driver-i386.c
+++ b/gcc/config/i386/driver-i386.c
@@ -423,6 +423,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
unsigned int has_ibt = 0, has_shstk = 0;
unsigned int has_avx512vnni = 0, has_vaes = 0;
unsigned int has_vpclmulqdq = 0;
+ unsigned int has_movdiri = 0, has_movdir64b = 0;
bool arch;
@@ -518,6 +519,8 @@ const char *host_detect_local_cpu (int argc, const char **argv)
has_vaes = ecx & bit_VAES;
has_vpclmulqdq = ecx & bit_VPCLMULQDQ;
has_avx512bitalg = ecx & bit_AVX512BITALG;
+ has_movdiri = ecx & bit_MOVDIRI;
+ has_movdir64b = ecx & bit_MOVDIR64B;
has_avx5124vnniw = edx & bit_AVX5124VNNIW;
has_avx5124fmaps = edx & bit_AVX5124FMAPS;
@@ -1097,6 +1100,8 @@ const char *host_detect_local_cpu (int argc, const char **argv)
const char *vaes = has_vaes ? " -mvaes" : " -mno-vaes";
const char *vpclmulqdq = has_vpclmulqdq ? " -mvpclmulqdq" : " -mno-vpclmulqdq";
const char *avx512bitalg = has_avx512bitalg ? " -mavx512bitalg" : " -mno-avx512bitalg";
+ const char *movdiri = has_movdiri ? " -mmovdiri" : " -mno-movdiri";
+ const char *movdir64b = has_movdir64b ? " -mmovdir64b" : " -mno-movdir64b";
options = concat (options, mmx, mmx3dnow, sse, sse2, sse3, ssse3,
sse4a, cx16, sahf, movbe, aes, sha, pclmul,
popcnt, abm, lwp, fma, fma4, xop, bmi, sgx, bmi2,
@@ -1109,7 +1114,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
avx512ifma, avx512vbmi, avx5124fmaps, avx5124vnniw,
clwb, mwaitx, clzero, pku, rdpid, gfni, ibt, shstk,
avx512vbmi2, avx512vnni, vaes, vpclmulqdq,
- avx512bitalg, NULL);
+ avx512bitalg, movdiri, movdir64b, NULL);
}
done:
diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def
index 08360d2..eec01a2 100644
--- a/gcc/config/i386/i386-builtin-types.def
+++ b/gcc/config/i386/i386-builtin-types.def
@@ -531,6 +531,8 @@ DEF_FUNCTION_TYPE (VOID, PFLOAT, V4SF)
DEF_FUNCTION_TYPE (VOID, PFLOAT, V8SF)
DEF_FUNCTION_TYPE (VOID, PFLOAT, V16SF)
DEF_FUNCTION_TYPE (VOID, PINT, INT)
+DEF_FUNCTION_TYPE (VOID, PUNSIGNED, UNSIGNED)
+DEF_FUNCTION_TYPE (VOID, PVOID, PCVOID)
DEF_FUNCTION_TYPE (VOID, PLONGLONG, LONGLONG)
DEF_FUNCTION_TYPE (VOID, PULONGLONG, ULONGLONG)
DEF_FUNCTION_TYPE (VOID, PV2SI, V2SI)
diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def
index 7b4ad2b..1b9c63a 100644
--- a/gcc/config/i386/i386-builtin.def
+++ b/gcc/config/i386/i386-builtin.def
@@ -417,6 +417,10 @@ BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, CODE_FOR_expandv8
BDESC (0, CODE_FOR_wbinvd, "__builtin_ia32_wbinvd", IX86_BUILTIN_WBINVD, UNKNOWN, (int) VOID_FTYPE_VOID)
+/* MOVDIRI. */
+BDESC (OPTION_MASK_ISA_MOVDIRI, CODE_FOR_movdirisi, "__builtin_ia32_directstoreu_u32", IX86_BUILTIN_MOVDIRISI32, UNKNOWN, (int) VOID_FTYPE_PUNSIGNED_UNSIGNED)
+BDESC (OPTION_MASK_ISA_MOVDIRI | OPTION_MASK_ISA_64BIT, CODE_FOR_movdiridi, "__builtin_ia32_directstoreu_u64", IX86_BUILTIN_MOVDIRIDI64, UNKNOWN, (int) VOID_FTYPE_PULONGLONG_ULONGLONG)
+
BDESC_END (SPECIAL_ARGS, ARGS)
/* Builtins with variable number of arguments. */
@@ -2841,6 +2845,7 @@ BDESC_END (ARGS2, SPECIAL_ARGS2)
BDESC_FIRST (special_args2, SPECIAL_ARGS2,
OPTION_MASK_ISA_WBNOINVD, CODE_FOR_wbnoinvd, "__builtin_ia32_wbnoinvd", IX86_BUILTIN_WBNOINVD, UNKNOWN, (int) VOID_FTYPE_VOID)
+BDESC (OPTION_MASK_ISA_MOVDIR64B, CODE_FOR_nothing, "__builtin_ia32_movdir64b", IX86_BUILTIN_MOVDIR64B, UNKNOWN, (int) VOID_FTYPE_PVOID_PCVOID)
BDESC_END (SPECIAL_ARGS2, MPX)
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index 2e0e9f6..b0bdaf8 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -515,6 +515,10 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
def_or_undef (parse_in, "__VAES__");
if (isa_flag & OPTION_MASK_ISA_VPCLMULQDQ)
def_or_undef (parse_in, "__VPCLMULQDQ__");
+ if (isa_flag & OPTION_MASK_ISA_MOVDIRI)
+ def_or_undef (parse_in, "__MOVDIRI__");
+ if (isa_flag2 & OPTION_MASK_ISA_MOVDIR64B)
+ def_or_undef (parse_in, "__MOVDIR64B__");
if (TARGET_IAMCU)
{
def_or_undef (parse_in, "__iamcu");
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d24c81b..ea221d6 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2770,7 +2770,8 @@ ix86_target_string (HOST_WIDE_INT isa, HOST_WIDE_INT isa2,
{ "-mhle", OPTION_MASK_ISA_HLE },
{ "-mmovbe", OPTION_MASK_ISA_MOVBE },
{ "-mclzero", OPTION_MASK_ISA_CLZERO },
- { "-mmwaitx", OPTION_MASK_ISA_MWAITX }
+ { "-mmwaitx", OPTION_MASK_ISA_MWAITX },
+ { "-mmovdir64b", OPTION_MASK_ISA_MOVDIR64B }
};
static struct ix86_target_opts isa_opts[] =
{
@@ -2833,7 +2834,8 @@ ix86_target_string (HOST_WIDE_INT isa, HOST_WIDE_INT isa2,
{ "-mlwp", OPTION_MASK_ISA_LWP },
{ "-mfxsr", OPTION_MASK_ISA_FXSR },
{ "-mclwb", OPTION_MASK_ISA_CLWB },
- { "-mshstk", OPTION_MASK_ISA_SHSTK }
+ { "-mshstk", OPTION_MASK_ISA_SHSTK },
+ { "-mmovdiri", OPTION_MASK_ISA_MOVDIRI }
};
/* Flag options. */
@@ -5419,6 +5421,8 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
IX86_ATTR_ISA ("shstk", OPT_mshstk),
IX86_ATTR_ISA ("vaes", OPT_mvaes),
IX86_ATTR_ISA ("vpclmulqdq", OPT_mvpclmulqdq),
+ IX86_ATTR_ISA ("movdiri", OPT_mmovdiri),
+ IX86_ATTR_ISA ("movdir64b", OPT_mmovdir64b),
/* enum options */
IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
@@ -35997,6 +36001,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
case VOID_FTYPE_PDOUBLE_V2DF:
case VOID_FTYPE_PLONGLONG_LONGLONG:
case VOID_FTYPE_PULONGLONG_ULONGLONG:
+ case VOID_FTYPE_PUNSIGNED_UNSIGNED:
case VOID_FTYPE_PINT_INT:
nargs = 1;
klass = store;
@@ -36026,6 +36031,12 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
break;
}
break;
+ case VOID_FTYPE_PVOID_PCVOID:
+ nargs = 1;
+ klass = store;
+ memory = 0;
+
+ break;
case V4SF_FTYPE_V4SF_PCV2SF:
case V2DF_FTYPE_V2DF_PCDOUBLE:
nargs = 2;
@@ -37166,6 +37177,24 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
emit_move_insn (target, op0);
return target;
+ case IX86_BUILTIN_MOVDIR64B:
+
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ arg1 = CALL_EXPR_ARG (exp, 1);
+ op0 = expand_normal (arg0);
+ op1 = expand_normal (arg1);
+ mode0 = (TARGET_64BIT ? DImode : SImode);
+
+ op0 = force_reg (mode0, op0);
+ if (!memory_operand (op1, mode0))
+ op1 = gen_rtx_MEM (mode0, op1);
+
+ insn = (TARGET_64BIT
+ ? gen_movdir64b_di (op0, op1)
+ : gen_movdir64b_si (op0, op1));
+ emit_insn (insn);
+ return 0;
+
case IX86_BUILTIN_FXSAVE:
case IX86_BUILTIN_FXRSTOR:
case IX86_BUILTIN_FXSAVE64:
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index c9f19b6..0b0f0d2 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -187,6 +187,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_IBT_P(x) TARGET_ISA_IBT_P(x)
#define TARGET_SHSTK TARGET_ISA_SHSTK
#define TARGET_SHSTK_P(x) TARGET_ISA_SHSTK_P(x)
+#define TARGET_MOVDIRI TARGET_ISA_MOVDIRI
+#define TARGET_MOVDIRI_P(x) TARGET_ISA_MOVDIRI_P(x)
+#define TARGET_MOVDIR64B TARGET_ISA_MOVDIR64B
+#define TARGET_MOVDIR64B_P(x) TARGET_ISA_MOVDIR64B_P(x)
#define TARGET_LP64 TARGET_ABI_64
#define TARGET_LP64_P(x) TARGET_ABI_64_P(x)
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 95ca2cf..fb5dcb8 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -289,6 +289,8 @@
UNSPECV_WRUSS
UNSPECV_SETSSBSY
UNSPECV_CLRSSBSY
+ UNSPECV_MOVDIRI
+ UNSPECV_MOVDIR64B
])
;; Constants to represent rounding modes in the ROUND instruction
@@ -20697,6 +20699,22 @@
"wbnoinvd"
[(set_attr "type" "other")])
+(define_insn "movdiri<mode>"
+ [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m")
+ (match_operand:SWI48 1 "register_operand" "r")]
+ UNSPECV_MOVDIRI)]
+ "TARGET_MOVDIRI"
+ "movdiri\t{%1, %0|%0, %1}"
+ [(set_attr "type" "other")])
+
+(define_insn "movdir64b_<mode>"
+ [(unspec_volatile:SWI48[(match_operand:SWI48 0 "register_operand" "r")
+ (match_operand:SWI48 1 "memory_operand")]
+ UNSPECV_MOVDIR64B)]
+ "TARGET_MOVDIR64B"
+ "movdir64b\t{%1, %0|%0, %1}"
+ [(set_attr "type" "other")])
+
(include "mmx.md")
(include "sse.md")
(include "sync.md")
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index c063ae8..95a52f9 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1057,3 +1057,11 @@ Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern)
mindirect-branch-register
Target Report Var(ix86_indirect_branch_register) Init(0)
Force indirect call and jump via register.
+
+mmovdiri
+Target Report Mask(ISA_MOVDIRI) Var(ix86_isa_flags) Save
+Support MOVDIRI built-in functions and code generation.
+
+mmovdir64b
+Target Report Mask(ISA_MOVDIR64B) Var(ix86_isa_flags2) Save
+Support MOVDIR64B built-in functions and code generation.
diff --git a/gcc/config/i386/immintrin.h b/gcc/config/i386/immintrin.h
index ad0fb21..63c5e59 100644
--- a/gcc/config/i386/immintrin.h
+++ b/gcc/config/i386/immintrin.h
@@ -110,6 +110,8 @@
#include <vpclmulqdqintrin.h>
+#include <movdirintrin.h>
+
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_wbinvd (void)
diff --git a/gcc/config/i386/movdirintrin.h b/gcc/config/i386/movdirintrin.h
new file mode 100644
index 0000000..8b4d0b3
--- /dev/null
+++ b/gcc/config/i386/movdirintrin.h
@@ -0,0 +1,74 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#if !defined _IMMINTRIN_H_INCLUDED
+# error "Never use <movdirintrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef _MOVDIRINTRIN_H_INCLUDED
+#define _MOVDIRINTRIN_H_INCLUDED
+
+#ifndef __MOVDIRI__
+#pragma GCC push_options
+#pragma GCC target ("movdiri")
+#define __DISABLE_MOVDIRI__
+#endif /* __MOVDIRI__ */
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_directstoreu_u32 (void * __P, unsigned int __A)
+{
+ __builtin_ia32_directstoreu_u32 ((unsigned int *)__P, __A);
+}
+#ifdef __x86_64__
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_directstoreu_u64 (void * __P, unsigned long long __A)
+{
+ __builtin_ia32_directstoreu_u64 ((unsigned long long *)__P, __A);
+}
+#endif
+
+#ifdef __DISABLE_MOVDIRI__
+#undef __DISABLE_MOVDIRI__
+#pragma GCC pop_options
+#endif /* __DISABLE_MOVDIRI__ */
+
+#ifndef __MOVDIR64B__
+#pragma GCC push_options
+#pragma GCC target ("movdir64b")
+#define __DISABLE_MOVDIR64B__
+#endif /* __MOVDIR64B__ */
+
+extern __inline void
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_movdir64b (void * __P, const void * __Q)
+{
+ __builtin_ia32_movdir64b (__P, __Q);
+}
+
+#ifdef __DISABLE_MOVDIR64B__
+#undef __DISABLE_MOVDIR64B__
+#pragma GCC pop_options
+#endif /* __DISABLE_MOVDIR64B__ */
+#endif /* _MOVDIRINTRIN_H_INCLUDED. */
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8c0d275..bf7a2a8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1262,7 +1262,7 @@ See RS/6000 and PowerPC Options.
-mlzcnt -mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp -mmpx @gol
-mmwaitx -mclzero -mpku -mthreads -mgfni -mvaes @gol
-mcet -mibt -mshstk -mforce-indirect-call -mavx512vbmi2 @gol
--mvpclmulqdq -mavx512bitalg -mavx512vpopcntdq @gol
+-mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -mavx512vpopcntdq @gol
-mms-bitfields -mno-align-stringops -minline-all-stringops @gol
-minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol
-mmemcpy-strategy=@var{strategy} -mmemset-strategy=@var{strategy} @gol
@@ -27314,6 +27314,12 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@itemx -mavx512bitalg
@opindex mavx512bitalg
@need 200
+@itemx -mmovdiri
+@opindex mmovdiri
+@need 200
+@itemx -mmovdir64b
+@opindex mmovdir64b
+@need 200
@itemx -mavx512vpopcntdq
@opindex mavx512vpopcntdq
These switches enable the use of instructions in the MMX, SSE,
@@ -27321,8 +27327,8 @@ SSE2, SSE3, SSSE3, SSE4.1, AVX, AVX2, AVX512F, AVX512PF, AVX512ER, AVX512CD,
SHA, AES, PCLMUL, FSGSBASE, RDRND, F16C, FMA, SSE4A, FMA4, XOP, LWP, ABM,
AVX512VL, AVX512BW, AVX512DQ, AVX512IFMA, AVX512VBMI, BMI, BMI2, VAES,
FXSR, XSAVE, XSAVEOPT, LZCNT, RTM, MPX, MWAITX, PKU, IBT, SHSTK, AVX512VBMI2,
-GFNI, VPCLMULQDQ, AVX512BITALG, AVX512VPOPCNTDQ3DNow!@: or enhanced 3DNow!@:
-extended instruction sets.
+GFNI, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B,
+AVX512VPOPCNTDQ3DNow!@: or enhanced 3DNow!@: extended instruction sets.
Each has a corresponding @option{-mno-} option to disable use of these
instructions.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 63f2be9..0af4982 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2018-04-19 Sebastian Peryt <sebastian.peryt@intel.com>
+
+ * gcc.target/i386/movdir-1.c: New test.
+
2018-04-19 Richard Biener <rguenther@suse.de>
PR middle-end/85455
diff --git a/gcc/testsuite/gcc.target/i386/movdir-1.c b/gcc/testsuite/gcc.target/i386/movdir-1.c
new file mode 100644
index 0000000..ebd3e2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/movdir-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-mmovdir64b -mmovdiri -O2" } */
+/* { dg-final { scan-assembler-times "movdiri" 1 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "movdiri" 2 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler "movdir64b\[ \\t\]" } } */
+
+#include <x86intrin.h>
+
+unsigned int w;
+void *x;
+unsigned long long q, *z;
+
+int
+main ()
+{
+
+ unsigned int array[] = {1, 2, 3, 4, 5};
+ unsigned int *ap = &w;
+
+ _directstoreu_u32(x, w);
+
+#ifdef __x86_64__
+ _directstoreu_u64(z, q);
+#endif
+
+ _movdir64b(ap, array);
+
+return 0;
+}
+