Hi, This patch add support for xsavec, xsaves ISA extensions, introduced in [1], and clflushopt introduced in [2].
[1]http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html [2]http://software.intel.com/en-us/file/319433-018pdf Bootstraps, passes make-check. Ok for trunk? Changelog: 2014-05-12 Ilya Tocar <ilya.to...@intel.com> * common/config/i386/i386-common.c (OPTION_MASK_ISA_CLFLUSHOPT_SET): Define. (OPTION_MASK_ISA_XSAVES_SET): Ditto. (OPTION_MASK_ISA_XSAVEC_SET): Ditto. (OPTION_MASK_ISA_CLFLUSHOPT_UNSET): Ditto. (OPTION_MASK_ISA_XSAVES_UNSET): Ditto. (OPTION_MASK_ISA_XSAVEC_UNSET): Ditto. (ix86_handle_option): Handle OPT_mxsavec, OPT_mxsaves, OPT_mclflushopt. * config.gcc (i[34567]86-*-*): Add clflushoptintrin.h, xsavecintrin.h, xsavesintrin.h. (x86_64-*-*): Ditto. * config/i386/clflushoptintrin.h: New. * config/i386/xsavecintrin.h: Ditto. * config/i386/xsavesintrin.h: Ditto. * config/i386/cpuid.h (bit_CLFLUSHOPT): Define. (bit_XSAVES): Ditto. (bit_XSAVES): Ditto. * config/i386/driver-i386.c (host_detect_local_cpu): Handle -mclflushopt, -mxsavec, -mxsaves, -mno-xsaves, -mno-xsavec, -mno-clflushopt. * config/i386/i386-c.c (ix86_target_macros_internal): Handle OPTION_MASK_ISA_CLFLUSHOPT, OPTION_MASK_ISA_XSAVEC, OPTION_MASK_ISA_XSAVES. * config/i386/i386.c (ix86_target_string): Handle -mclflushopt, -mxsavec, -mxsaves. (PTA_CLFLUSHOPT) Define. (PTA_XSAVEC): Ditto. (PTA_XSAVES): Ditto. (ix86_option_override_internal): Handle new options. (ix86_valid_target_attribute_inner_p): Ditto. (ix86_builtins): Add IX86_BUILTIN_XSAVEC, IX86_BUILTIN_XSAVEC64, IX86_BUILTIN_XSAVES, IX86_BUILTIN_XRSTORS, IX86_BUILTIN_XSAVES64, IX86_BUILTIN_XRSTORS64, IX86_BUILTIN_CLFLUSHOPT. (bdesc_special_args): Add __builtin_ia32_xsaves, __builtin_ia32_xrstors, __builtin_ia32_xsavec, __builtin_ia32_xsaves64, __builtin_ia32_xrstors64, __builtin_ia32_xsavec64. (ix86_init_mmx_sse_builtins): Add __builtin_ia32_clflushopt. (ix86_expand_builtin): Handle new builtins. * config/i386/i386.h (TARGET_CLFLUSHOPT) Define. (TARGET_CLFLUSHOPT_P): Ditto. (TARGET_XSAVEC): Ditto. (TARGET_XSAVEC_P): Ditto. (TARGET_XSAVES): Ditto. (TARGET_XSAVES_P): Ditto. * config/i386/i386.md (ANY_XSAVE): Add UNSPECV_XSAVEC, UNSPECV_XSAVES. (ANY_XSAVE64)" Add UNSPECV_XSAVEC64, UNSPECV_XSAVES64. (attr xsave): Add xsavec, xsavec64, xsaves, xsaves64. (ANY_XRSTOR): New. (ANY_XRSTOR64): Ditto. (xrstor): Ditto. (xrstor): Change into <xrstor>. (xrstor_rex64): Change into <xrstor>_rex64. (xrstor64): Change into <xrstor>64 (clflushopt): New. * config/i386/i386.opt (mclflushopt): New. (mxsavec): Ditto. (mxsaves): Ditto. * config/i386/x86intrin.h: Add clflushoptintrin.h, xsavesintrin.h, xsavecintrin.h. * doc/invoke.texi: Document new options. And for tests: 2014-05-12 Ilya Tocar <ilya.to...@intel.com> * gcc.target/i386/clflushopt-1.c: New. * gcc.target/i386/xsavec-1.c: Ditto. * gcc.target/i386/xsavec64-1.c: Ditto. * gcc.target/i386/xsaves-1.c: Ditto. * gcc.target/i386/xsaves64-1.c: Ditto. gcc/common/config/i386/i386-common.c | 47 ++++++++++++++++ gcc/config.gcc | 6 +- gcc/config/i386/clflushoptintrin.h | 49 ++++++++++++++++ gcc/config/i386/cpuid.h | 3 + gcc/config/i386/driver-i386.c | 12 +++- gcc/config/i386/i386-c.c | 6 ++ gcc/config/i386/i386.c | 83 +++++++++++++++++++++++++++- gcc/config/i386/i386.h | 6 ++ gcc/config/i386/i386.md | 64 +++++++++++++++++---- gcc/config/i386/i386.opt | 12 ++++ gcc/config/i386/x86intrin.h | 6 ++ gcc/config/i386/xsavecintrin.h | 58 +++++++++++++++++++ gcc/config/i386/xsavesintrin.h | 72 ++++++++++++++++++++++++ gcc/doc/invoke.texi | 7 +++ gcc/testsuite/gcc.target/i386/clflushopt-1.c | 11 ++++ gcc/testsuite/gcc.target/i386/xsavec-1.c | 11 ++++ gcc/testsuite/gcc.target/i386/xsavec64-1.c | 11 ++++ gcc/testsuite/gcc.target/i386/xsaves-1.c | 13 +++++ gcc/testsuite/gcc.target/i386/xsaves64-1.c | 13 +++++ 19 files changed, 474 insertions(+), 16 deletions(-) create mode 100644 gcc/config/i386/clflushoptintrin.h create mode 100644 gcc/config/i386/xsavecintrin.h create mode 100644 gcc/config/i386/xsavesintrin.h create mode 100644 gcc/testsuite/gcc.target/i386/clflushopt-1.c create mode 100644 gcc/testsuite/gcc.target/i386/xsavec-1.c create mode 100644 gcc/testsuite/gcc.target/i386/xsavec64-1.c create mode 100644 gcc/testsuite/gcc.target/i386/xsaves-1.c create mode 100644 gcc/testsuite/gcc.target/i386/xsaves64-1.c diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c index a6ab555..3012783 100644 --- a/gcc/common/config/i386/i386-common.c +++ b/gcc/common/config/i386/i386-common.c @@ -70,6 +70,11 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA_RDSEED_SET OPTION_MASK_ISA_RDSEED #define OPTION_MASK_ISA_ADX_SET OPTION_MASK_ISA_ADX #define OPTION_MASK_ISA_PREFETCHWT1_SET OPTION_MASK_ISA_PREFETCHWT1 +#define OPTION_MASK_ISA_CLFLUSHOPT_SET OPTION_MASK_ISA_CLFLUSHOPT +#define OPTION_MASK_ISA_XSAVES_SET \ + (OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_XSAVE) +#define OPTION_MASK_ISA_XSAVEC_SET \ + (OPTION_MASK_ISA_XSAVEC | OPTION_MASK_ISA_XSAVE) /* SSE4 includes both SSE4.1 and SSE4.2. -msse4 should be the same as -msse4.2. */ @@ -156,6 +161,9 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA_RDSEED_UNSET OPTION_MASK_ISA_RDSEED #define OPTION_MASK_ISA_ADX_UNSET OPTION_MASK_ISA_ADX #define OPTION_MASK_ISA_PREFETCHWT1_UNSET OPTION_MASK_ISA_PREFETCHWT1 +#define OPTION_MASK_ISA_CLFLUSHOPT_UNSET OPTION_MASK_ISA_CLFLUSHOPT +#define OPTION_MASK_ISA_XSAVEC_UNSET OPTION_MASK_ISA_XSAVEC +#define OPTION_MASK_ISA_XSAVES_UNSET OPTION_MASK_ISA_XSAVES /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same as -mno-sse4.1. */ @@ -720,6 +728,32 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_mxsavec: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_XSAVEC_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XSAVEC_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_XSAVEC_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XSAVEC_UNSET; + } + return true; + + case OPT_mxsaves: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_XSAVES_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XSAVES_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_XSAVES_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XSAVES_UNSET; + } + return true; + case OPT_mrdseed: if (value) { @@ -772,6 +806,19 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_mclflushopt: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_CLFLUSHOPT_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_CLFLUSHOPT_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_CLFLUSHOPT_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_CLFLUSHOPT_UNSET; + } + return true; + /* Comes from final.c -- no real reason to change it. */ #define MAX_CODE_ALIGN 16 diff --git a/gcc/config.gcc b/gcc/config.gcc index 81205ff..fa99023 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -375,7 +375,8 @@ i[34567]86-*-*) rtmintrin.h xtestintrin.h rdseedintrin.h prfchwintrin.h adxintrin.h fxsrintrin.h xsaveintrin.h xsaveoptintrin.h avx512cdintrin.h avx512erintrin.h avx512pfintrin.h - shaintrin.h" + shaintrin.h clflushoptintrin.h xsavecintrin.h + xsavesintrin.h" ;; x86_64-*-*) cpu_type=i386 @@ -392,7 +393,8 @@ x86_64-*-*) rtmintrin.h xtestintrin.h rdseedintrin.h prfchwintrin.h adxintrin.h fxsrintrin.h xsaveintrin.h xsaveoptintrin.h avx512cdintrin.h avx512erintrin.h avx512pfintrin.h - shaintrin.h" + shaintrin.h clflushoptintrin.h xsavecintrin.h + xsavesintrin.h" need_64bit_hwint=yes ;; ia64-*-*) diff --git a/gcc/config/i386/clflushoptintrin.h b/gcc/config/i386/clflushoptintrin.h new file mode 100644 index 0000000..0265612 --- /dev/null +++ b/gcc/config/i386/clflushoptintrin.h @@ -0,0 +1,49 @@ +/* Copyright (C) 2013 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 _X86INTRIN_H_INCLUDED +# error "Never use <clflushoptintrin.h> directly; include <x86intrin.h> instead." +#endif + +#ifndef _CLFLUSHOPTINTRIN_H_INCLUDED +#define _CLFLUSHOPTINTRIN_H_INCLUDED + +#ifndef __CLFLUSHOPT__ +#pragma GCC push_options +#pragma GCC target("clflushopt") +#define __DISABLE_CLFLUSHOPT__ +#endif /* __CLFLUSHOPT__ */ + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_clflushopt (void *__A) +{ + __builtin_ia32_clflushopt (__A); +} + +#ifdef __DISABLE_CLFLUSHOPT__ +#undef __DISABLE_CLFLUSHOPT__ +#pragma GCC pop_options +#endif /* __DISABLE_CLFLUSHOPT__ */ + +#endif /* _CLFLUSHOPTINTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 8c323ae..7ac22a1 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -75,6 +75,7 @@ #define bit_AVX512F (1 << 16) #define bit_RDSEED (1 << 18) #define bit_ADX (1 << 19) +#define bit_CLFLUSHOPT (1 << 23) #define bit_AVX512PF (1 << 26) #define bit_AVX512ER (1 << 27) #define bit_AVX512CD (1 << 28) @@ -85,6 +86,8 @@ /* Extended State Enumeration Sub-leaf (%eax == 13, %ecx == 1) */ #define bit_XSAVEOPT (1 << 0) +#define bit_XSAVEC (1 << 1) +#define bit_XSAVES (1 << 3) /* Signatures for different CPU implementations as returned in uses of cpuid with level 0. */ diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index 1f5a11c..3e8a995 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -410,6 +410,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) unsigned int has_osxsave = 0, has_fxsr = 0, has_xsave = 0, has_xsaveopt = 0; unsigned int has_avx512er = 0, has_avx512pf = 0, has_avx512cd = 0; unsigned int has_avx512f = 0, has_sha = 0, has_prefetchwt1 = 0; + unsigned int has_clflushopt = 0, has_xsavec = 0, has_xsaves = 0; bool arch; @@ -486,6 +487,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) has_avx512pf = ebx & bit_AVX512PF; has_avx512cd = ebx & bit_AVX512CD; has_sha = ebx & bit_SHA; + has_clflushopt = ebx & bit_CLFLUSHOPT; has_prefetchwt1 = ecx & bit_PREFETCHWT1; } @@ -495,6 +497,8 @@ const char *host_detect_local_cpu (int argc, const char **argv) __cpuid_count (13, 1, eax, ebx, ecx, edx); has_xsaveopt = eax & bit_XSAVEOPT; + has_xsavec = eax & bit_XSAVEC; + has_xsaves = eax & bit_XSAVES; } /* Check cpuid level of extended features. */ @@ -541,6 +545,8 @@ const char *host_detect_local_cpu (int argc, const char **argv) has_xop = 0; has_xsave = 0; has_xsaveopt = 0; + has_xsaves = 0; + has_xsavec = 0; } if (!arch) @@ -886,6 +892,9 @@ const char *host_detect_local_cpu (int argc, const char **argv) const char *avx512cd = has_avx512cd ? " -mavx512cd" : " -mno-avx512cd"; const char *avx512pf = has_avx512pf ? " -mavx512pf" : " -mno-avx512pf"; const char *prefetchwt1 = has_prefetchwt1 ? " -mprefetchwt1" : " -mno-prefetchwt1"; + const char *clflushopt = has_clflushopt ? " -mclflushopt" : " -mno-clflushopt"; + const char *xsavec = has_xsavec ? " -mxsavec" : " -mno-xsavec"; + const char *xsaves = has_xsaves ? " -mxsaves" : " -mno-xsaves"; options = concat (options, mmx, mmx3dnow, sse, sse2, sse3, ssse3, sse4a, cx16, sahf, movbe, aes, sha, pclmul, @@ -893,7 +902,8 @@ const char *host_detect_local_cpu (int argc, const char **argv) tbm, avx, avx2, sse4_2, sse4_1, lzcnt, rtm, hle, rdrnd, f16c, fsgsbase, rdseed, prfchw, adx, fxsr, xsave, xsaveopt, avx512f, avx512er, - avx512cd, avx512pf, prefetchwt1, NULL); + avx512cd, avx512pf, prefetchwt1, clflushopt, + xsavec, xsaves, NULL); } done: diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index 2c31dc8..2c05cec 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -393,6 +393,12 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__SSE_MATH__"); if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE2)) def_or_undef (parse_in, "__SSE2_MATH__"); + if (isa_flag & OPTION_MASK_ISA_CLFLUSHOPT) + def_or_undef (parse_in, "__CLFLUSHOPT__"); + if (isa_flag & OPTION_MASK_ISA_XSAVEC) + def_or_undef (parse_in, "__XSAVEC__"); + if (isa_flag & OPTION_MASK_ISA_XSAVES) + def_or_undef (parse_in, "__XSAVES__"); } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 01ad5e5..77afd81 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2625,6 +2625,9 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch, { "-mxsave", OPTION_MASK_ISA_XSAVE }, { "-mxsaveopt", OPTION_MASK_ISA_XSAVEOPT }, { "-mprefetchwt1", OPTION_MASK_ISA_PREFETCHWT1 }, + { "-mclflushopt", OPTION_MASK_ISA_CLFLUSHOPT }, + { "-mxsavec", OPTION_MASK_ISA_XSAVEC }, + { "-mxsaves", OPTION_MASK_ISA_XSAVES }, }; /* Flag options. */ @@ -3116,6 +3119,9 @@ ix86_option_override_internal (bool main_args_p, #define PTA_AVX512CD (HOST_WIDE_INT_1 << 43) #define PTA_SHA (HOST_WIDE_INT_1 << 45) #define PTA_PREFETCHWT1 (HOST_WIDE_INT_1 << 46) +#define PTA_CLFLUSHOPT (HOST_WIDE_INT_1 << 47) +#define PTA_XSAVEC (HOST_WIDE_INT_1 << 48) +#define PTA_XSAVES (HOST_WIDE_INT_1 << 49) #define PTA_CORE2 \ (PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 \ @@ -3673,6 +3679,15 @@ ix86_option_override_internal (bool main_args_p, if (processor_alias_table[i].flags & PTA_PREFETCHWT1 && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_PREFETCHWT1)) opts->x_ix86_isa_flags |= OPTION_MASK_ISA_PREFETCHWT1; + if (processor_alias_table[i].flags & PTA_CLFLUSHOPT + && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_CLFLUSHOPT)) + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_CLFLUSHOPT; + if (processor_alias_table[i].flags & PTA_XSAVEC + && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_XSAVEC)) + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_XSAVEC; + if (processor_alias_table[i].flags & PTA_XSAVES + && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_XSAVES)) + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_XSAVES; if (processor_alias_table[i].flags & (PTA_PREFETCH_SSE | PTA_SSE)) x86_prefetch_sse = true; @@ -4556,6 +4571,9 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[], IX86_ATTR_ISA ("xsave", OPT_mxsave), IX86_ATTR_ISA ("xsaveopt", OPT_mxsaveopt), IX86_ATTR_ISA ("prefetchwt1", OPT_mprefetchwt1), + IX86_ATTR_ISA ("clflushopt", OPT_mclflushopt), + IX86_ATTR_ISA ("xsavec", OPT_mxsavec), + IX86_ATTR_ISA ("xsaves", OPT_mxsaves), /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), @@ -27281,6 +27299,14 @@ enum ix86_builtins IX86_BUILTIN_XSAVEOPT, IX86_BUILTIN_XSAVEOPT64, + IX86_BUILTIN_XSAVEC, + IX86_BUILTIN_XSAVEC64, + + IX86_BUILTIN_XSAVES, + IX86_BUILTIN_XRSTORS, + IX86_BUILTIN_XSAVES64, + IX86_BUILTIN_XRSTORS64, + /* 3DNow! Original */ IX86_BUILTIN_FEMMS, IX86_BUILTIN_PAVGUSB, @@ -28476,6 +28502,9 @@ enum ix86_builtins IX86_BUILTIN_SHA256MSG2, IX86_BUILTIN_SHA256RNDS2, + /* CLFLUSHOPT instructions. */ + IX86_BUILTIN_CLFLUSHOPT, + /* TFmode support builtins. */ IX86_BUILTIN_INFQ, IX86_BUILTIN_HUGE_VALQ, @@ -28935,18 +28964,24 @@ static const struct builtin_description bdesc_special_args[] = /* 3DNow! */ { OPTION_MASK_ISA_3DNOW, CODE_FOR_mmx_femms, "__builtin_ia32_femms", IX86_BUILTIN_FEMMS, UNKNOWN, (int) VOID_FTYPE_VOID }, - /* FXSR, XSAVE and XSAVEOPT */ + /* FXSR, XSAVE, XSAVEOPT, XSAVEC and XSAVES. */ { OPTION_MASK_ISA_FXSR, CODE_FOR_nothing, "__builtin_ia32_fxsave", IX86_BUILTIN_FXSAVE, UNKNOWN, (int) VOID_FTYPE_PVOID }, { OPTION_MASK_ISA_FXSR, CODE_FOR_nothing, "__builtin_ia32_fxrstor", IX86_BUILTIN_FXRSTOR, UNKNOWN, (int) VOID_FTYPE_PVOID }, { OPTION_MASK_ISA_XSAVE, CODE_FOR_nothing, "__builtin_ia32_xsave", IX86_BUILTIN_XSAVE, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, { OPTION_MASK_ISA_XSAVE, CODE_FOR_nothing, "__builtin_ia32_xrstor", IX86_BUILTIN_XRSTOR, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, { OPTION_MASK_ISA_XSAVEOPT, CODE_FOR_nothing, "__builtin_ia32_xsaveopt", IX86_BUILTIN_XSAVEOPT, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, + { OPTION_MASK_ISA_XSAVES, CODE_FOR_nothing, "__builtin_ia32_xsaves", IX86_BUILTIN_XSAVES, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, + { OPTION_MASK_ISA_XSAVES, CODE_FOR_nothing, "__builtin_ia32_xrstors", IX86_BUILTIN_XRSTORS, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, + { OPTION_MASK_ISA_XSAVEC, CODE_FOR_nothing, "__builtin_ia32_xsavec", IX86_BUILTIN_XSAVEC, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, { OPTION_MASK_ISA_FXSR | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_fxsave64", IX86_BUILTIN_FXSAVE64, UNKNOWN, (int) VOID_FTYPE_PVOID }, { OPTION_MASK_ISA_FXSR | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_fxrstor64", IX86_BUILTIN_FXRSTOR64, UNKNOWN, (int) VOID_FTYPE_PVOID }, { OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_xsave64", IX86_BUILTIN_XSAVE64, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, { OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_xrstor64", IX86_BUILTIN_XRSTOR64, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, { OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_xsaveopt64", IX86_BUILTIN_XSAVEOPT64, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, + { OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_xsaves64", IX86_BUILTIN_XSAVES64, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, + { OPTION_MASK_ISA_XSAVES | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_xrstors64", IX86_BUILTIN_XRSTORS64, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, + { OPTION_MASK_ISA_XSAVEC | OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_xsavec64", IX86_BUILTIN_XSAVEC64, UNKNOWN, (int) VOID_FTYPE_PVOID_INT64 }, /* SSE */ { OPTION_MASK_ISA_SSE, CODE_FOR_sse_storeups, "__builtin_ia32_storeups", IX86_BUILTIN_STOREUPS, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V4SF }, @@ -31124,6 +31159,9 @@ ix86_init_mmx_sse_builtins (void) def_builtin (OPTION_MASK_ISA_64BIT, "__builtin_ia32_writeeflags_u64", VOID_FTYPE_UINT64, IX86_BUILTIN_WRITE_FLAGS); + /* CLFLUSHOPT. */ + def_builtin (OPTION_MASK_ISA_CLFLUSHOPT, "__builtin_ia32_clflushopt", + VOID_FTYPE_PCVOID, IX86_BUILTIN_CLFLUSHOPT); /* Add FMA4 multi-arg argument instructions */ for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++) @@ -35056,6 +35094,16 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, emit_insn (gen_sse2_clflush (op0)); return 0; + case IX86_BUILTIN_CLFLUSHOPT: + arg0 = CALL_EXPR_ARG (exp, 0); + op0 = expand_normal (arg0); + icode = CODE_FOR_clflushopt; + if (!insn_data[icode].operand[0].predicate (op0, Pmode)) + op0 = ix86_zero_extend_to_Pmode (op0); + + emit_insn (gen_clflushopt (op0)); + return 0; + case IX86_BUILTIN_MONITOR: arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); @@ -35247,6 +35295,12 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_XRSTOR64: case IX86_BUILTIN_XSAVEOPT: case IX86_BUILTIN_XSAVEOPT64: + case IX86_BUILTIN_XSAVES: + case IX86_BUILTIN_XRSTORS: + case IX86_BUILTIN_XSAVES64: + case IX86_BUILTIN_XRSTORS64: + case IX86_BUILTIN_XSAVEC: + case IX86_BUILTIN_XSAVEC64: arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); op0 = expand_normal (arg0); @@ -35285,6 +35339,24 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_XSAVEOPT64: icode = CODE_FOR_xsaveopt64; break; + case IX86_BUILTIN_XSAVES: + icode = CODE_FOR_xsaves_rex64; + break; + case IX86_BUILTIN_XRSTORS: + icode = CODE_FOR_xrstors_rex64; + break; + case IX86_BUILTIN_XSAVES64: + icode = CODE_FOR_xsaves64; + break; + case IX86_BUILTIN_XRSTORS64: + icode = CODE_FOR_xrstors64; + break; + case IX86_BUILTIN_XSAVEC: + icode = CODE_FOR_xsavec_rex64; + break; + case IX86_BUILTIN_XSAVEC64: + icode = CODE_FOR_xsavec64; + break; default: gcc_unreachable (); } @@ -35306,6 +35378,15 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, case IX86_BUILTIN_XSAVEOPT: icode = CODE_FOR_xsaveopt; break; + case IX86_BUILTIN_XSAVES: + icode = CODE_FOR_xsaves; + break; + case IX86_BUILTIN_XRSTORS: + icode = CODE_FOR_xrstors; + break; + case IX86_BUILTIN_XSAVEC: + icode = CODE_FOR_xsavec; + break; default: gcc_unreachable (); } diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 1a884d8..c94916f 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -104,6 +104,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define TARGET_AES_P(x) TARGET_ISA_AES_P(x) #define TARGET_SHA TARGET_ISA_SHA #define TARGET_SHA_P(x) TARGET_ISA_SHA_P(x) +#define TARGET_CLFLUSHOPT TARGET_ISA_CLFLUSHOPT +#define TARGET_CLFLUSHOPT_P(x) TARGET_ISA_CLFLUSHOPT_P(x) +#define TARGET_XSAVEC TARGET_ISA_XSAVEC +#define TARGET_XSAVEC_P(x) TARGET_ISA_XSAVEC_P(x) +#define TARGET_XSAVES TARGET_ISA_XSAVES +#define TARGET_XSAVES_P(x) TARGET_ISA_XSAVES_P(x) #define TARGET_PCLMUL TARGET_ISA_PCLMUL #define TARGET_PCLMUL_P(x) TARGET_ISA_PCLMUL_P(x) #define TARGET_CMPXCHG16B TARGET_ISA_CX16 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index fde0a93..9728427 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -213,6 +213,12 @@ UNSPECV_XRSTOR64 UNSPECV_XSAVEOPT UNSPECV_XSAVEOPT64 + UNSPECV_XSAVES + UNSPECV_XRSTORS + UNSPECV_XSAVES64 + UNSPECV_XRSTORS64 + UNSPECV_XSAVEC + UNSPECV_XSAVEC64 ;; For atomic compound assignments. UNSPECV_FNSTENV @@ -233,6 +239,9 @@ UNSPECV_XTEST UNSPECV_NLGR + + ;; For CLFLUSHOPT support + UNSPECV_CLFLUSHOPT ]) ;; Constants to represent rounding modes in the ROUND instruction @@ -17786,17 +17795,39 @@ (define_int_iterator ANY_XSAVE [UNSPECV_XSAVE - (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")]) + (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT") + (UNSPECV_XSAVEC "TARGET_XSAVEC") + (UNSPECV_XSAVES "TARGET_XSAVES")]) (define_int_iterator ANY_XSAVE64 [UNSPECV_XSAVE64 - (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")]) + (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT") + (UNSPECV_XSAVEC64 "TARGET_XSAVEC") + (UNSPECV_XSAVES64 "TARGET_XSAVES")]) (define_int_attr xsave [(UNSPECV_XSAVE "xsave") (UNSPECV_XSAVE64 "xsave64") (UNSPECV_XSAVEOPT "xsaveopt") - (UNSPECV_XSAVEOPT64 "xsaveopt64")]) + (UNSPECV_XSAVEOPT64 "xsaveopt64") + (UNSPECV_XSAVEC "xsavec") + (UNSPECV_XSAVEC64 "xsavec64") + (UNSPECV_XSAVES "xsaves") + (UNSPECV_XSAVES64 "xsaves64")]) + +(define_int_iterator ANY_XRSTOR + [UNSPECV_XRSTOR + (UNSPECV_XRSTORS "TARGET_XSAVES")]) + +(define_int_iterator ANY_XRSTOR64 + [UNSPECV_XRSTOR64 + (UNSPECV_XRSTORS64 "TARGET_XSAVES")]) + +(define_int_attr xrstor + [(UNSPECV_XRSTOR "xrstor") + (UNSPECV_XRSTOR64 "xrstor") + (UNSPECV_XRSTORS "xrstors") + (UNSPECV_XRSTORS64 "xrstors")]) (define_insn "<xsave>" [(set (match_operand:BLK 0 "memory_operand" "=m") @@ -17836,39 +17867,39 @@ (set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) -(define_insn "xrstor" +(define_insn "<xrstor>" [(unspec_volatile:BLK [(match_operand:BLK 0 "memory_operand" "m") (match_operand:DI 1 "register_operand" "A")] - UNSPECV_XRSTOR)] + ANY_XRSTOR)] "!TARGET_64BIT && TARGET_XSAVE" - "xrstor\t%0" + "<xrstor>\t%0" [(set_attr "type" "other") (set_attr "memory" "load") (set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) -(define_insn "xrstor_rex64" +(define_insn "<xrstor>_rex64" [(unspec_volatile:BLK [(match_operand:BLK 0 "memory_operand" "m") (match_operand:SI 1 "register_operand" "a") (match_operand:SI 2 "register_operand" "d")] - UNSPECV_XRSTOR)] + ANY_XRSTOR)] "TARGET_64BIT && TARGET_XSAVE" - "xrstor\t%0" + "<xrstor>\t%0" [(set_attr "type" "other") (set_attr "memory" "load") (set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) -(define_insn "xrstor64" +(define_insn "<xrstor>64" [(unspec_volatile:BLK [(match_operand:BLK 0 "memory_operand" "m") (match_operand:SI 1 "register_operand" "a") (match_operand:SI 2 "register_operand" "d")] - UNSPECV_XRSTOR64)] + ANY_XRSTOR64)] "TARGET_64BIT && TARGET_XSAVE" - "xrstor64\t%0" + "<xrstor>64\t%0" [(set_attr "type" "other") (set_attr "memory" "load") (set (attr "length") @@ -18166,6 +18197,15 @@ [(set_attr "type" "other") (set_attr "length" "3")]) +(define_insn "clflushopt" + [(unspec_volatile [(match_operand 0 "address_operand" "p")] + UNSPECV_CLFLUSHOPT)] + "TARGET_CLFLUSHOPT" + "clflushopt\t%a0" + [(set_attr "type" "sse") + (set_attr "atom_sse_attr" "fence") + (set_attr "memory" "unknown")]) + (include "mmx.md") (include "sse.md") (include "sync.md") diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 0f463a2..dc1302c 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -697,6 +697,10 @@ madx Target Report Mask(ISA_ADX) Var(ix86_isa_flags) Save Support flag-preserving add-carry instructions +mclflushopt +Target Report Mask(ISA_CLFLUSHOPT) Var(ix86_isa_flags) Save +Support CLFLUSHOPT instructions + mfxsr Target Report Mask(ISA_FXSR) Var(ix86_isa_flags) Save Support FXSAVE and FXRSTOR instructions @@ -709,6 +713,14 @@ mxsaveopt Target Report Mask(ISA_XSAVEOPT) Var(ix86_isa_flags) Save Support XSAVEOPT instruction +mxsavec +Target Report Mask(ISA_XSAVEC) Var(ix86_isa_flags) Save +Support XSAVEC instructions + +mxsaves +Target Report Mask(ISA_XSAVES) Var(ix86_isa_flags) Save +Support XSAVES and XRSTORS instructions + mtbm Target Report Mask(ISA_TBM) Var(ix86_isa_flags) Save Support TBM built-in functions and code generation diff --git a/gcc/config/i386/x86intrin.h b/gcc/config/i386/x86intrin.h index 80e9e6f..c84ab88 100644 --- a/gcc/config/i386/x86intrin.h +++ b/gcc/config/i386/x86intrin.h @@ -75,4 +75,10 @@ #include <adxintrin.h> +#include <clflushoptintrin.h> + +#include <xsavesintrin.h> + +#include <xsavecintrin.h> + #endif /* _X86INTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/xsavecintrin.h b/gcc/config/i386/xsavecintrin.h new file mode 100644 index 0000000..99fadd5 --- /dev/null +++ b/gcc/config/i386/xsavecintrin.h @@ -0,0 +1,58 @@ +/* Copyright (C) 2014 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 _X86INTRIN_H_INCLUDED +# error "Never use <xsavecintrin.h> directly; include <x86intrin.h> instead." +#endif + +#ifndef _XSAVECINTRIN_H_INCLUDED +#define _XSAVECINTRIN_H_INCLUDED + +#ifndef __XSAVEC__ +#pragma GCC push_options +#pragma GCC target("xsavec") +#define __DISABLE_XSAVEC__ +#endif /* __XSAVEC__ */ + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xsavec (void *__P, long long __M) +{ + __builtin_ia32_xsavec (__P, __M); +} + +#ifdef __x86_64__ +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xsavec64 (void *__P, long long __M) +{ + __builtin_ia32_xsavec64 (__P, __M); +} +#endif + +#ifdef __DISABLE_XSAVEC__ +#undef __DISABLE_XSAVEC__ +#pragma GCC pop_options +#endif /* __DISABLE_XSAVEC__ */ + +#endif /* _XSAVECINTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/xsavesintrin.h b/gcc/config/i386/xsavesintrin.h new file mode 100644 index 0000000..a08a81a --- /dev/null +++ b/gcc/config/i386/xsavesintrin.h @@ -0,0 +1,72 @@ +/* Copyright (C) 2014 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 _X86INTRIN_H_INCLUDED +# error "Never use <xsavesintrin.h> directly; include <x86intrin.h> instead." +#endif + +#ifndef _XSAVESINTRIN_H_INCLUDED +#define _XSAVESINTRIN_H_INCLUDED + +#ifndef __XSAVES__ +#pragma GCC push_options +#pragma GCC target("xsaves") +#define __DISABLE_XSAVES__ +#endif /* __XSAVES__ */ + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xsaves (void *__P, long long __M) +{ + __builtin_ia32_xsaves (__P, __M); +} + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xrstors (void *__P, long long __M) +{ + __builtin_ia32_xrstors (__P, __M); +} + +#ifdef __x86_64__ +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xrstors64 (void *__P, long long __M) +{ + __builtin_ia32_xrstors64 (__P, __M); +} + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xsaves64 (void *__P, long long __M) +{ + __builtin_ia32_xsaves64 (__P, __M); +} +#endif + +#ifdef __DISABLE_XSAVES__ +#undef __DISABLE_XSAVES__ +#pragma GCC pop_options +#endif /* __DISABLE_XSAVES__ */ + +#endif /* _XSAVESINTRIN_H_INCLUDED */ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 3fe9d5f..411ef11 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -670,6 +670,7 @@ Objective-C and Objective-C++ Dialects}. -mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx @gol -mavx2 -mavx512f -mavx512pf -mavx512er -mavx512cd -msha @gol -maes -mpclmul -mfsgsbase -mrdrnd -mf16c -mfma -mprefetchwt1 @gol +-mclflushopt -mxsavec -mxsaves @gol -msse4a -m3dnow -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop -mlzcnt @gol -mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp -mthreads @gol -mno-align-stringops -minline-all-stringops @gol @@ -15312,6 +15313,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. @itemx -mno-aes @itemx -mpclmul @itemx -mno-pclmul +@itemx -mclfushopt +@itemx -mno-clflsuhopt @need 800 @itemx -mfsgsbase @itemx -mno-fsgsbase @@ -15350,6 +15353,10 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. @itemx -mrtm @itemx -mtbm @itemx -mno-tbm +@itemx -mxsavec +@itemx -mno-xsavec +@itemx -mxsaves +@itemx -mno-xsaves @opindex mmmx @opindex mno-mmx @opindex msse diff --git a/gcc/testsuite/gcc.target/i386/clflushopt-1.c b/gcc/testsuite/gcc.target/i386/clflushopt-1.c new file mode 100644 index 0000000..7569373 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/clflushopt-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mclflushopt" } */ +/* { dg-final { scan-assembler "clflushopt\[ \\t\]" } } */ + +#include "x86intrin.h" + +void +test_clflushopt (void *__A) +{ + _mm_clflushopt (__A); +} diff --git a/gcc/testsuite/gcc.target/i386/xsavec-1.c b/gcc/testsuite/gcc.target/i386/xsavec-1.c new file mode 100644 index 0000000..3be71b8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xsavec-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mxsavec" } */ +/* { dg-final { scan-assembler "xsavec\[ \\t\]" } } */ + +#include "x86intrin.h" + +void +test_xsavec (void *__A, long long __B) +{ + _xsavec (__A, __B); +} diff --git a/gcc/testsuite/gcc.target/i386/xsavec64-1.c b/gcc/testsuite/gcc.target/i386/xsavec64-1.c new file mode 100644 index 0000000..5d4faff --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xsavec64-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -mxsavec" } */ +/* { dg-final { scan-assembler "xsavec64\[ \\t\]" } } */ + +#include "x86intrin.h" + +void +test_xsavec (void *__A, long long __B) +{ + _xsavec64 (__A, __B); +} diff --git a/gcc/testsuite/gcc.target/i386/xsaves-1.c b/gcc/testsuite/gcc.target/i386/xsaves-1.c new file mode 100644 index 0000000..05ff765 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xsaves-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mxsaves" } */ +/* { dg-final { scan-assembler "xsaves\[ \\t\]" } } */ +/* { dg-final { scan-assembler "xrstors\[ \\t\]" } } */ + +#include "x86intrin.h" + +void +test_xsaves (void *__A, long long __B) +{ + _xsaves (__A, __B); + _xrstors (__A, __B); +} diff --git a/gcc/testsuite/gcc.target/i386/xsaves64-1.c b/gcc/testsuite/gcc.target/i386/xsaves64-1.c new file mode 100644 index 0000000..a3725d2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xsaves64-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -mxsaves" } */ +/* { dg-final { scan-assembler "xsaves64\[ \\t\]" } } */ +/* { dg-final { scan-assembler "xrstors64\[ \\t\]" } } */ + +#include "x86intrin.h" + +void +test_xsaves (void *__A, long long __B) +{ + _xsaves64 (__A, __B); + _xrstors64 (__A, __B); +} -- 1.8.3.1