+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
#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. */
#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. */
}
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)
{
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
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
#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)
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;
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;
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,
avx512ifma, avx512vbmi, avx5124fmaps, avx5124vnniw,
clwb, mwaitx, clzero, pku, rdpid, gfni, ibt, shstk,
avx512vbmi2, avx512vnni, vaes, vpclmulqdq,
- avx512bitalg, NULL);
+ avx512bitalg, movdiri, movdir64b, NULL);
}
done:
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)
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. */
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)
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");
{ "-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[] =
{
{ "-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. */
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_),
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;
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;
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:
#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)
UNSPECV_WRUSS
UNSPECV_SETSSBSY
UNSPECV_CLRSSBSY
+ UNSPECV_MOVDIRI
+ UNSPECV_MOVDIR64B
])
;; Constants to represent rounding modes in the ROUND instruction
"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")
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.
#include <vpclmulqdqintrin.h>
+#include <movdirintrin.h>
+
extern __inline void
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
_wbinvd (void)
--- /dev/null
+/* 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. */
-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
@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,
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.
+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
--- /dev/null
+/* { 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;
+}
+