diff options
33 files changed, 812 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e79d3367bfa..4d0f9e00dc6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,58 @@ +2012-10-26 Alexander Ivchenko <alexander.ivchenko@intel.com> + Uros Bizjak <ubizjak@gmail.com> + + * gcc/common/config/i386/i386-common.c + (OPTION_MASK_ISA_FXSR_SET): New. + (OPTION_MASK_ISA_XSAVE_SET): Likewise. + (OPTION_MASK_ISA_XSAVEOPT_SET): Likewise. + (ix86_handle_option): Handle mfxsr, mxsave, mxsaveopt options. + * gcc/config.gcc (i[34567]86-*-*): Add fxsrintrin.h, + xsaveintrin.h, xsaveoptintrin.h. + (x86_64-*-*): Likewise. + * config/i386/fxsrintrin.h: New header. + * config/i386/xsaveintrin.h: Likewise. + * config/i386/xsaveoptintrin.h: Likewise. + * gcc/config/i386/driver-i386.c (host_detect_local_cpu): Detect + FXSR/XSAVE/XSAVEOPT support. + * gcc/config/i386/i386-builtin-types.def + (VOID_FTYPE_PVOID_INT64): New function type. + * gcc/config/i386/i386-c.c: Define __FXSR__, __XSAVE__ + and __XSAVEOPT__ if needed. + * gcc/config/i386/i386.c (ix86_target_string): Define -mfxsr, + -mxsave and -mxsaveopt options. + (PTA_FXSR): New. + (PTA_XSAVE): Likewise. + (PTA_XSAVEOPT): Likewise. + (ix86_option_override_internal): Handle new option. + (processor_alias_table): Added PTA_FXSR, PTA_XSAVE, PTA_XSAVEOPT. + (ix86_valid_target_attribute_inner_p): Add OPT_mfxsr, + OPT_mxsave, OPT_mxsaveopt. + (ix86_builtins): Add IX86_BUILTIN_FXSAVE, IX86_BUILTIN_FXRSTOR, + IX86_BUILTIN_FXSAVE64, IX86_BUILTIN_XSAVE, IX86_BUILTIN_XSAVE64, + IX86_BUILTIN_XRSTOR, IX86_BUILTIN_XRSTOR64, IX86_BUILTIN_XSAVEOPT, + IX86_BUILTIN_XSAVEOPT64. + (ix86_expand_builtin): Handle these built-ins. + * gcc/config/i386/i386.h (TARGET_FXSR): New. + (TARGET_XSAVE): Likewise. + (TARGET_XSAVEOPT): Likewise. + * gcc/config/i386/i386.md (ANY_XSAVE): New int iterator. + (ANY_XSAVE64): Likewise. + (xsave): New int attribute. + (fxsave): New instruction. + (fxsave64): Likewise. + (fxrstor): Likewise. + (fxrstor64): Likewise. + (<xsave>): Likewise. + (<xsave>_rex64): Likewise. + (xrstor): Likewise. + (xrstor_rex64): Likewise. + (xrstor64): Likewise. + * gcc/config/i386/i386.opt (mfxsr): New. + (mxsave): Likewise. + (mxsaveopt): Likewise. + * gcc/config/i386/x86intrin.h: Include + xsaveintrin.h, fxsrintrin.h, xsaveoptintrin.h. + 2012-10-26 Ralf Corsépius <ralf.corsepius@rtems.org> * config/avr/t-rtems: Revert previous commit. diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c index e05cd562f44..da3967ea8c6 100644 --- a/gcc/common/config/i386/i386-common.c +++ b/gcc/common/config/i386/i386-common.c @@ -49,11 +49,16 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA_SSE4_2_SET \ (OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_SSE4_1_SET) #define OPTION_MASK_ISA_AVX_SET \ - (OPTION_MASK_ISA_AVX | OPTION_MASK_ISA_SSE4_2_SET) + (OPTION_MASK_ISA_AVX | OPTION_MASK_ISA_SSE4_2_SET \ + | OPTION_MASK_ISA_XSAVE_SET) #define OPTION_MASK_ISA_FMA_SET \ (OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_AVX_SET) #define OPTION_MASK_ISA_AVX2_SET \ (OPTION_MASK_ISA_AVX2 | OPTION_MASK_ISA_AVX_SET) +#define OPTION_MASK_ISA_FXSR_SET OPTION_MASK_ISA_FXSR +#define OPTION_MASK_ISA_XSAVE_SET OPTION_MASK_ISA_XSAVE +#define OPTION_MASK_ISA_XSAVEOPT_SET \ + (OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_XSAVE) #define OPTION_MASK_ISA_RTM_SET OPTION_MASK_ISA_RTM #define OPTION_MASK_ISA_PRFCHW_SET OPTION_MASK_ISA_PRFCHW #define OPTION_MASK_ISA_RDSEED_SET OPTION_MASK_ISA_RDSEED @@ -122,9 +127,13 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA_AVX_UNSET \ (OPTION_MASK_ISA_AVX | OPTION_MASK_ISA_FMA_UNSET \ | OPTION_MASK_ISA_FMA4_UNSET | OPTION_MASK_ISA_F16C_UNSET \ - | OPTION_MASK_ISA_AVX2_UNSET) + | OPTION_MASK_ISA_AVX2_UNSET | OPTION_MASK_ISA_XSAVE_UNSET) #define OPTION_MASK_ISA_FMA_UNSET OPTION_MASK_ISA_FMA #define OPTION_MASK_ISA_AVX2_UNSET OPTION_MASK_ISA_AVX2 +#define OPTION_MASK_ISA_FXSR_UNSET OPTION_MASK_ISA_FXSR +#define OPTION_MASK_ISA_XSAVE_UNSET \ + (OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_XSAVEOPT_UNSET) +#define OPTION_MASK_ISA_XSAVEOPT_UNSET OPTION_MASK_ISA_XSAVEOPT #define OPTION_MASK_ISA_RTM_UNSET OPTION_MASK_ISA_RTM #define OPTION_MASK_ISA_PRFCHW_UNSET OPTION_MASK_ISA_PRFCHW #define OPTION_MASK_ISA_RDSEED_UNSET OPTION_MASK_ISA_RDSEED @@ -574,6 +583,45 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_mfxsr: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_FXSR_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FXSR_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_FXSR_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_FXSR_UNSET; + } + return true; + + case OPT_mxsave: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_XSAVE_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XSAVE_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_XSAVE_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XSAVE_UNSET; + } + return true; + + case OPT_mxsaveopt: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_XSAVEOPT_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XSAVEOPT_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_XSAVEOPT_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_XSAVEOPT_UNSET; + } + return true; + case OPT_mrdseed: if (value) { diff --git a/gcc/config.gcc b/gcc/config.gcc index cb67cfc32a7..52e6426be86 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -368,7 +368,8 @@ i[34567]86-*-*) ia32intrin.h cross-stdarg.h lwpintrin.h popcntintrin.h lzcntintrin.h bmiintrin.h bmi2intrin.h tbmintrin.h avx2intrin.h fmaintrin.h f16cintrin.h rtmintrin.h - xtestintrin.h rdseedintrin.h prfchwintrin.h adxintrin.h" + xtestintrin.h rdseedintrin.h prfchwintrin.h adxintrin.h + fxsrintrin.h xsaveintrin.h xsaveoptintrin.h" ;; x86_64-*-*) cpu_type=i386 @@ -382,7 +383,8 @@ x86_64-*-*) ia32intrin.h cross-stdarg.h lwpintrin.h popcntintrin.h lzcntintrin.h bmiintrin.h tbmintrin.h bmi2intrin.h avx2intrin.h fmaintrin.h f16cintrin.h rtmintrin.h - xtestintrin.h rdseedintrin.h prfchwintrin.h adxintrin.h" + xtestintrin.h rdseedintrin.h prfchwintrin.h adxintrin.h + fxsrintrin.h xsaveintrin.h xsaveoptintrin.h" need_64bit_hwint=yes ;; ia64-*-*) diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 5cd1eb1c736..1f76d3a5077 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -75,6 +75,9 @@ #define bit_RDSEED (1 << 18) #define bit_ADX (1 << 19) +/* Extended State Enumeration Sub-leaf (%eax == 13, %ecx == 1) */ +#define bit_XSAVEOPT (1 << 0) + /* Signatures for different CPU implementations as returned in uses of cpuid with level 0. */ #define signature_AMD_ebx 0x68747541 diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c index 36d80b1e621..940060a97f3 100644 --- a/gcc/config/i386/driver-i386.c +++ b/gcc/config/i386/driver-i386.c @@ -390,7 +390,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) unsigned int has_hle = 0, has_rtm = 0; unsigned int has_rdrnd = 0, has_f16c = 0, has_fsgsbase = 0; unsigned int has_rdseed = 0, has_prfchw = 0, has_adx = 0; - unsigned int has_osxsave = 0; + unsigned int has_osxsave = 0, has_fxsr = 0, has_xsave = 0, has_xsaveopt = 0; bool arch; @@ -441,10 +441,12 @@ const char *host_detect_local_cpu (int argc, const char **argv) has_fma = ecx & bit_FMA; has_f16c = ecx & bit_F16C; has_rdrnd = ecx & bit_RDRND; + has_xsave = ecx & bit_XSAVE; has_cmpxchg8b = edx & bit_CMPXCHG8B; has_cmov = edx & bit_CMOV; has_mmx = edx & bit_MMX; + has_fxsr = edx & bit_FXSAVE; has_sse = edx & bit_SSE; has_sse2 = edx & bit_SSE2; @@ -462,6 +464,13 @@ const char *host_detect_local_cpu (int argc, const char **argv) has_adx = ebx & bit_ADX; } + if (max_level >= 13) + { + __cpuid_count (13, 1, eax, ebx, ecx, edx); + + has_xsaveopt = eax & bit_XSAVEOPT; + } + /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */ #define XCR_XFEATURE_ENABLED_MASK 0x0 #define XSTATE_FP 0x1 @@ -481,6 +490,8 @@ const char *host_detect_local_cpu (int argc, const char **argv) has_fma = 0; has_fma4 = 0; has_xop = 0; + has_xsave = 0; + has_xsaveopt = 0; } /* Check cpuid level of extended features. */ @@ -763,11 +774,15 @@ const char *host_detect_local_cpu (int argc, const char **argv) const char *rdseed = has_rdseed ? " -mrdseed" : " -mno-rdseed"; const char *prfchw = has_prfchw ? " -mprfchw" : " -mno-prfchw"; const char *adx = has_adx ? " -madx" : " -mno-adx"; + const char *fxsr = has_fxsr ? " -mfxsr" : " -mno-fxsr"; + const char *xsave = has_xsave ? " -mxsave" : " -mno-xsave"; + const char *xsaveopt = has_xsaveopt ? " -mxsaveopt" : " -mno-xsaveopt"; options = concat (options, cx16, sahf, movbe, ase, pclmul, popcnt, abm, lwp, fma, fma4, xop, bmi, bmi2, tbm, avx, avx2, sse4_2, sse4_1, lzcnt, rtm, - hle, rdrnd, f16c, fsgsbase, rdseed, prfchw, adx, NULL); + hle, rdrnd, f16c, fsgsbase, rdseed, prfchw, adx, + fxsr, xsave, xsaveopt, NULL); } done: diff --git a/gcc/config/i386/fxsrintrin.h b/gcc/config/i386/fxsrintrin.h new file mode 100644 index 00000000000..9f5e411ac32 --- /dev/null +++ b/gcc/config/i386/fxsrintrin.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2012 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 && !defined _IMMINTRIN_H_INCLUDED */ +/* # error "Never use <fxsrintrin.h> directly; include <x86intrin.h> instead." */ +/* #endif */ + +#ifndef _FXSRINTRIN_H_INCLUDED +#define _FXSRINTRIN_H_INCLUDED + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_fxsave (void *__P) +{ + return __builtin_ia32_fxsave (__P); +} + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_fxrstor (void *__P) +{ + return __builtin_ia32_fxrstor (__P); +} + +#ifdef __x86_64__ +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_fxsave64 (void *__P) +{ + return __builtin_ia32_fxsave64 (__P); +} + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_fxrstor64 (void *__P) +{ + return __builtin_ia32_fxrstor64 (__P); +} +#endif + +#endif /* _FXSRINTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def index 8a199c0a7f8..314f3e888d8 100644 --- a/gcc/config/i386/i386-builtin-types.def +++ b/gcc/config/i386/i386-builtin-types.def @@ -356,6 +356,7 @@ DEF_FUNCTION_TYPE (V4DI, V4DI, V2DI) DEF_FUNCTION_TYPE (V4DI, PCV4DI, V4DI) DEF_FUNCTION_TYPE (V4DI, V4DI, INT) DEF_FUNCTION_TYPE (V2DI, V4DI, INT) +DEF_FUNCTION_TYPE (VOID, PVOID, INT64) DEF_FUNCTION_TYPE (VOID, PCHAR, V16QI) DEF_FUNCTION_TYPE (VOID, PCHAR, V32QI) DEF_FUNCTION_TYPE (VOID, PDOUBLE, V2DF) diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index edd64ff7ae3..bd02fbb1bfa 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -302,6 +302,12 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__PRFCHW__"); if (isa_flag & OPTION_MASK_ISA_ADX) def_or_undef (parse_in, "__ADX__"); + if (isa_flag & OPTION_MASK_ISA_FXSR) + def_or_undef (parse_in, "__FXSR__"); + if (isa_flag & OPTION_MASK_ISA_XSAVE) + def_or_undef (parse_in, "__XSAVE__"); + if (isa_flag & OPTION_MASK_ISA_XSAVEOPT) + def_or_undef (parse_in, "__XSAVEOPT__"); if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE)) def_or_undef (parse_in, "__SSE_MATH__"); if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE2)) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index c98c6b7a52f..2a9db18b173 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2752,7 +2752,7 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch, preceding options while match those first. */ static struct ix86_target_opts isa_opts[] = { - { "-mfma4", OPTION_MASK_ISA_FMA4 }, + { "-mfma4", OPTION_MASK_ISA_FMA4 }, { "-mfma", OPTION_MASK_ISA_FMA }, { "-mxop", OPTION_MASK_ISA_XOP }, { "-mlwp", OPTION_MASK_ISA_LWP }, @@ -2760,17 +2760,18 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch, { "-msse4.2", OPTION_MASK_ISA_SSE4_2 }, { "-msse4.1", OPTION_MASK_ISA_SSE4_1 }, { "-mssse3", OPTION_MASK_ISA_SSSE3 }, - { "-msse3", OPTION_MASK_ISA_SSE3 }, - { "-msse2", OPTION_MASK_ISA_SSE2 }, + { "-msse3", OPTION_MASK_ISA_SSE3 }, + { "-msse2", OPTION_MASK_ISA_SSE2 }, { "-msse", OPTION_MASK_ISA_SSE }, { "-m3dnow", OPTION_MASK_ISA_3DNOW }, { "-m3dnowa", OPTION_MASK_ISA_3DNOW_A }, { "-mmmx", OPTION_MASK_ISA_MMX }, { "-mabm", OPTION_MASK_ISA_ABM }, { "-mbmi", OPTION_MASK_ISA_BMI }, - { "-mbmi2", OPTION_MASK_ISA_BMI2 }, + { "-mbmi2", OPTION_MASK_ISA_BMI2 }, { "-mlzcnt", OPTION_MASK_ISA_LZCNT }, { "-mhle", OPTION_MASK_ISA_HLE }, + { "-mfxsr", OPTION_MASK_ISA_FXSR }, { "-mrdseed", OPTION_MASK_ISA_RDSEED }, { "-mprfchw", OPTION_MASK_ISA_PRFCHW }, { "-madx", OPTION_MASK_ISA_ADX }, @@ -2782,8 +2783,10 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch, { "-mpclmul", OPTION_MASK_ISA_PCLMUL }, { "-mfsgsbase", OPTION_MASK_ISA_FSGSBASE }, { "-mrdrnd", OPTION_MASK_ISA_RDRND }, - { "-mf16c", OPTION_MASK_ISA_F16C }, + { "-mf16c", OPTION_MASK_ISA_F16C }, { "-mrtm", OPTION_MASK_ISA_RTM }, + { "-mxsave", OPTION_MASK_ISA_XSAVE }, + { "-mxsaveopt", OPTION_MASK_ISA_XSAVEOPT }, }; /* Flag options. */ @@ -3054,6 +3057,10 @@ ix86_option_override_internal (bool main_args_p) #define PTA_PRFCHW (HOST_WIDE_INT_1 << 34) #define PTA_RDSEED (HOST_WIDE_INT_1 << 35) #define PTA_ADX (HOST_WIDE_INT_1 << 36) +#define PTA_FXSR (HOST_WIDE_INT_1 << 37) +#define PTA_XSAVE (HOST_WIDE_INT_1 << 38) +#define PTA_XSAVEOPT (HOST_WIDE_INT_1 << 39) + /* if this reaches 64, need to widen struct pta flags below */ static struct pta @@ -3076,46 +3083,48 @@ ix86_option_override_internal (bool main_args_p) {"c3-2", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, PTA_MMX | PTA_SSE}, {"i686", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, 0}, {"pentiumpro", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, 0}, - {"pentium2", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, PTA_MMX}, + {"pentium2", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, PTA_MMX | PTA_FXSR}, {"pentium3", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, - PTA_MMX | PTA_SSE}, + PTA_MMX | PTA_SSE | PTA_FXSR}, {"pentium3m", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, - PTA_MMX | PTA_SSE}, + PTA_MMX | PTA_SSE | PTA_FXSR}, {"pentium-m", PROCESSOR_PENTIUMPRO, CPU_PENTIUMPRO, - PTA_MMX | PTA_SSE | PTA_SSE2}, + PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_FXSR}, {"pentium4", PROCESSOR_PENTIUM4, CPU_NONE, - PTA_MMX |PTA_SSE | PTA_SSE2}, + PTA_MMX |PTA_SSE | PTA_SSE2 | PTA_FXSR}, {"pentium4m", PROCESSOR_PENTIUM4, CPU_NONE, - PTA_MMX | PTA_SSE | PTA_SSE2}, + PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_FXSR}, {"prescott", PROCESSOR_NOCONA, CPU_NONE, - PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3}, + PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_FXSR}, {"nocona", PROCESSOR_NOCONA, CPU_NONE, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 - | PTA_CX16 | PTA_NO_SAHF}, + | PTA_CX16 | PTA_NO_SAHF | PTA_FXSR}, {"core2", PROCESSOR_CORE2_64, CPU_CORE2, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 - | PTA_SSSE3 | PTA_CX16}, + | PTA_SSSE3 | PTA_CX16 | PTA_FXSR}, {"corei7", PROCESSOR_COREI7_64, CPU_COREI7, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 - | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_CX16}, + | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_CX16 | PTA_FXSR}, {"corei7-avx", PROCESSOR_COREI7_64, CPU_COREI7, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AVX - | PTA_CX16 | PTA_POPCNT | PTA_AES | PTA_PCLMUL}, + | PTA_CX16 | PTA_POPCNT | PTA_AES | PTA_PCLMUL + | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT}, {"core-avx-i", PROCESSOR_COREI7_64, CPU_COREI7, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AVX | PTA_CX16 | PTA_POPCNT | PTA_AES | PTA_PCLMUL | PTA_FSGSBASE - | PTA_RDRND | PTA_F16C}, + | PTA_RDRND | PTA_F16C | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT}, {"core-avx2", PROCESSOR_COREI7_64, CPU_COREI7, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AVX | PTA_AVX2 | PTA_CX16 | PTA_POPCNT | PTA_AES | PTA_PCLMUL | PTA_FSGSBASE | PTA_RDRND | PTA_F16C | PTA_BMI | PTA_BMI2 | PTA_LZCNT - | PTA_FMA | PTA_MOVBE | PTA_RTM | PTA_HLE}, + | PTA_FMA | PTA_MOVBE | PTA_RTM | PTA_HLE | PTA_FXSR | PTA_XSAVE + | PTA_XSAVEOPT}, {"atom", PROCESSOR_ATOM, CPU_ATOM, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 - | PTA_SSSE3 | PTA_CX16 | PTA_MOVBE}, + | PTA_SSSE3 | PTA_CX16 | PTA_MOVBE | PTA_FXSR}, {"geode", PROCESSOR_GEODE, CPU_GEODE, PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_PREFETCH_SSE}, {"k6", PROCESSOR_K6, CPU_K6, PTA_MMX}, @@ -3156,7 +3165,7 @@ ix86_option_override_internal (bool main_args_p) | PTA_SSE2 | PTA_NO_SAHF}, {"amdfam10", PROCESSOR_AMDFAM10, CPU_AMDFAM10, PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE - | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM}, + | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM}, {"barcelona", PROCESSOR_AMDFAM10, CPU_AMDFAM10, PTA_64BIT | PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM}, @@ -3164,21 +3173,24 @@ ix86_option_override_internal (bool main_args_p) PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_FMA4 - | PTA_XOP | PTA_LWP | PTA_PRFCHW}, + | PTA_XOP | PTA_LWP | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE + | PTA_XSAVEOPT}, {"bdver2", PROCESSOR_BDVER2, CPU_BDVER2, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_FMA4 | PTA_XOP | PTA_LWP | PTA_BMI | PTA_TBM | PTA_F16C - | PTA_FMA | PTA_PRFCHW}, + | PTA_FMA | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT}, {"btver1", PROCESSOR_BTVER1, CPU_GENERIC64, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 - | PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_PRFCHW}, + | PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_PRFCHW + | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT}, {"btver2", PROCESSOR_BTVER2, CPU_GENERIC64, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_SSE4_1 | PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX - | PTA_BMI | PTA_F16C | PTA_MOVBE | PTA_PRFCHW}, + | PTA_BMI | PTA_F16C | PTA_MOVBE | PTA_PRFCHW + | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT}, {"generic32", PROCESSOR_GENERIC32, CPU_PENTIUMPRO, PTA_HLE /* flags are only used for -march switch. */ }, @@ -3549,6 +3561,15 @@ ix86_option_override_internal (bool main_args_p) if (processor_alias_table[i].flags & PTA_ADX && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_ADX)) ix86_isa_flags |= OPTION_MASK_ISA_ADX; + if (processor_alias_table[i].flags & PTA_FXSR + && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_FXSR)) + ix86_isa_flags |= OPTION_MASK_ISA_FXSR; + if (processor_alias_table[i].flags & PTA_XSAVE + && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_XSAVE)) + ix86_isa_flags |= OPTION_MASK_ISA_XSAVE; + if (processor_alias_table[i].flags & PTA_XSAVEOPT + && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_XSAVEOPT)) + ix86_isa_flags |= OPTION_MASK_ISA_XSAVEOPT; if (processor_alias_table[i].flags & (PTA_PREFETCH_SSE | PTA_SSE)) x86_prefetch_sse = true; @@ -4368,6 +4389,9 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[], IX86_ATTR_ISA ("prfchw", OPT_mprfchw), IX86_ATTR_ISA ("rdseed", OPT_mrdseed), IX86_ATTR_ISA ("adx", OPT_madx), + IX86_ATTR_ISA ("fxsr", OPT_mfxsr), + IX86_ATTR_ISA ("xsave", OPT_mxsave), + IX86_ATTR_ISA ("xsaveopt", OPT_mxsaveopt), /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), @@ -25570,6 +25594,19 @@ enum ix86_builtins IX86_BUILTIN_STMXCSR, IX86_BUILTIN_SFENCE, + IX86_BUILTIN_FXSAVE, + IX86_BUILTIN_FXRSTOR, + IX86_BUILTIN_FXSAVE64, + IX86_BUILTIN_FXRSTOR64, + + IX86_BUILTIN_XSAVE, + IX86_BUILTIN_XRSTOR, + IX86_BUILTIN_XSAVE64, + IX86_BUILTIN_XRSTOR64, + + IX86_BUILTIN_XSAVEOPT, + IX86_BUILTIN_XSAVEOPT64, + /* 3DNow! Original */ IX86_BUILTIN_FEMMS, IX86_BUILTIN_PAVGUSB, @@ -26776,6 +26813,19 @@ 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 */ + { 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_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 }, + /* SSE */ { OPTION_MASK_ISA_SSE, CODE_FOR_sse_storeups, "__builtin_ia32_storeups", IX86_BUILTIN_STOREUPS, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V4SF }, { OPTION_MASK_ISA_SSE, CODE_FOR_sse_movntv4sf, "__builtin_ia32_movntps", IX86_BUILTIN_MOVNTPS, UNKNOWN, (int) VOID_FTYPE_PFLOAT_V4SF }, @@ -30690,6 +30740,118 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, emit_move_insn (target, op0); return target; + case IX86_BUILTIN_FXSAVE: + case IX86_BUILTIN_FXRSTOR: + case IX86_BUILTIN_FXSAVE64: + case IX86_BUILTIN_FXRSTOR64: + switch (fcode) + { + case IX86_BUILTIN_FXSAVE: + icode = CODE_FOR_fxsave; + break; + case IX86_BUILTIN_FXRSTOR: + icode = CODE_FOR_fxrstor; + break; + case IX86_BUILTIN_FXSAVE64: + icode = CODE_FOR_fxsave64; + break; + case IX86_BUILTIN_FXRSTOR64: + icode = CODE_FOR_fxrstor64; + break; + default: + gcc_unreachable (); + } + + arg0 = CALL_EXPR_ARG (exp, 0); + op0 = expand_normal (arg0); + + if (!address_operand (op0, VOIDmode)) + { + op0 = convert_memory_address (Pmode, op0); + op0 = copy_addr_to_reg (op0); + } + op0 = gen_rtx_MEM (BLKmode, op0); + + pat = GEN_FCN (icode) (op0); + if (pat) + emit_insn (pat); + return 0; + + case IX86_BUILTIN_XSAVE: + case IX86_BUILTIN_XRSTOR: + case IX86_BUILTIN_XSAVE64: + case IX86_BUILTIN_XRSTOR64: + case IX86_BUILTIN_XSAVEOPT: + case IX86_BUILTIN_XSAVEOPT64: + arg0 = CALL_EXPR_ARG (exp, 0); + arg1 = CALL_EXPR_ARG (exp, 1); + op0 = expand_normal (arg0); + op1 = expand_normal (arg1); + + if (!address_operand (op0, VOIDmode)) + { + op0 = convert_memory_address (Pmode, op0); + op0 = copy_addr_to_reg (op0); + } + op0 = gen_rtx_MEM (BLKmode, op0); + + op1 = force_reg (DImode, op1); + + if (TARGET_64BIT) + { + op2 = expand_simple_binop (DImode, LSHIFTRT, op1, GEN_INT (32), + NULL, 1, OPTAB_DIRECT); + switch (fcode) + { + case IX86_BUILTIN_XSAVE: + icode = CODE_FOR_xsave_rex64; + break; + case IX86_BUILTIN_XRSTOR: + icode = CODE_FOR_xrstor_rex64; + break; + case IX86_BUILTIN_XSAVE64: + icode = CODE_FOR_xsave64; + break; + case IX86_BUILTIN_XRSTOR64: + icode = CODE_FOR_xrstor64; + break; + case IX86_BUILTIN_XSAVEOPT: + icode = CODE_FOR_xsaveopt_rex64; + break; + case IX86_BUILTIN_XSAVEOPT64: + icode = CODE_FOR_xsaveopt64; + break; + default: + gcc_unreachable (); + } + + op2 = gen_lowpart (SImode, op2); + op1 = gen_lowpart (SImode, op1); + pat = GEN_FCN (icode) (op0, op1, op2); + } + else + { + switch (fcode) + { + case IX86_BUILTIN_XSAVE: + icode = CODE_FOR_xsave; + break; + case IX86_BUILTIN_XRSTOR: + icode = CODE_FOR_xrstor; + break; + case IX86_BUILTIN_XSAVEOPT: + icode = CODE_FOR_xsaveopt; + break; + default: + gcc_unreachable (); + } + pat = GEN_FCN (icode) (op0, op1); + } + + if (pat) + emit_insn (pat); + return 0; + case IX86_BUILTIN_LLWPCB: arg0 = CALL_EXPR_ARG (exp, 0); op0 = expand_normal (arg0); diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index f923a973b64..712d00a5ed8 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -79,6 +79,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define TARGET_RDSEED TARGET_ISA_RDSEED #define TARGET_PRFCHW TARGET_ISA_PRFCHW #define TARGET_ADX TARGET_ISA_ADX +#define TARGET_FXSR TARGET_ISA_FXSR +#define TARGET_XSAVE TARGET_ISA_XSAVE +#define TARGET_XSAVEOPT TARGET_ISA_XSAVEOPT #define TARGET_LP64 TARGET_ABI_64 #define TARGET_X32 TARGET_ABI_X32 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 049d53494f9..63d64acf23d 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -202,6 +202,16 @@ UNSPECV_RDGSBASE UNSPECV_WRFSBASE UNSPECV_WRGSBASE + UNSPECV_FXSAVE + UNSPECV_FXRSTOR + UNSPECV_FXSAVE64 + UNSPECV_FXRSTOR64 + UNSPECV_XSAVE + UNSPECV_XRSTOR + UNSPECV_XSAVE64 + UNSPECV_XRSTOR64 + UNSPECV_XSAVEOPT + UNSPECV_XSAVEOPT64 ;; For RDRAND support UNSPECV_RDRAND @@ -18031,6 +18041,142 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; +;; FXSR, XSAVE and XSAVEOPT instructions +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_insn "fxsave" + [(set (match_operand:BLK 0 "memory_operand" "=m") + (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))] + "TARGET_FXSR" + "fxsave\t%0" + [(set_attr "type" "other") + (set_attr "memory" "store") + (set (attr "length") + (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) + +(define_insn "fxsave64" + [(set (match_operand:BLK 0 "memory_operand" "=m") + (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))] + "TARGET_64BIT && TARGET_FXSR" + "fxsave64\t%0" + [(set_attr "type" "other") + (set_attr "memory" "store") + (set (attr "length") + (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) + +(define_insn "fxrstor" + [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] + UNSPECV_FXRSTOR)] + "TARGET_FXSR" + "fxrstor\t%0" + [(set_attr "type" "other") + (set_attr "memory" "load") + (set (attr "length") + (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) + +(define_insn "fxrstor64" + [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] + UNSPECV_FXRSTOR64)] + "TARGET_64BIT && TARGET_FXSR" + "fxrstor64\t%0" + [(set_attr "type" "other") + (set_attr "memory" "load") + (set (attr "length") + (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) + +(define_int_iterator ANY_XSAVE + [UNSPECV_XSAVE + (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")]) + +(define_int_iterator ANY_XSAVE64 + [UNSPECV_XSAVE64 + (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")]) + +(define_int_attr xsave + [(UNSPECV_XSAVE "xsave") + (UNSPECV_XSAVE64 "xsave64") + (UNSPECV_XSAVEOPT "xsaveopt") + (UNSPECV_XSAVEOPT64 "xsaveopt64")]) + +(define_insn "<xsave>" + [(set (match_operand:BLK 0 "memory_operand" "=m") + (unspec_volatile:BLK + [(match_operand:DI 1 "register_operand" "A")] + ANY_XSAVE))] + "!TARGET_64BIT && TARGET_XSAVE" + "<xsave>\t%0" + [(set_attr "type" "other") + (set_attr "memory" "store") + (set (attr "length") + (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) + +(define_insn "<xsave>_rex64" + [(set (match_operand:BLK 0 "memory_operand" "=m") + (unspec_volatile:BLK + [(match_operand:SI 1 "register_operand" "a") + (match_operand:SI 2 "register_operand" "d")] + ANY_XSAVE))] + "TARGET_64BIT && TARGET_XSAVE" + "<xsave>\t%0" + [(set_attr "type" "other") + (set_attr "memory" "store") + (set (attr "length") + (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) + +(define_insn "<xsave>" + [(set (match_operand:BLK 0 "memory_operand" "=m") + (unspec_volatile:BLK + [(match_operand:SI 1 "register_operand" "a") + (match_operand:SI 2 "register_operand" "d")] + ANY_XSAVE64))] + "TARGET_64BIT && TARGET_XSAVE" + "<xsave>\t%0" + [(set_attr "type" "other") + (set_attr "memory" "store") + (set (attr "length") + (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) + +(define_insn "xrstor" + [(unspec_volatile:BLK + [(match_operand:BLK 0 "memory_operand" "m") + (match_operand:DI 1 "register_operand" "A")] + UNSPECV_XRSTOR)] + "!TARGET_64BIT && TARGET_XSAVE" + "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" + [(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)] + "TARGET_64BIT && TARGET_XSAVE" + "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" + [(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)] + "TARGET_64BIT && TARGET_XSAVE" + "xrstor64\t%0" + [(set_attr "type" "other") + (set_attr "memory" "load") + (set (attr "length") + (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; LWP instructions ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 6a389947d90..dc59c479fe8 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -552,6 +552,18 @@ madx Target Report Mask(ISA_ADX) Var(ix86_isa_flags) Save Support flag-preserving add-carry instructions +mfxsr +Target Report Mask(ISA_FXSR) Var(ix86_isa_flags) Save +Support FXSAVE and FXRSTOR instructions + +mxsave +Target Report Mask(ISA_XSAVE) Var(ix86_isa_flags) Save +Support XSAVE and XRSTOR instructions + +mxsaveopt +Target Report Mask(ISA_XSAVEOPT) Var(ix86_isa_flags) Save +Support XSAVEOPT instruction + 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 fae6491c49f..8b6df7a0fd7 100644 --- a/gcc/config/i386/x86intrin.h +++ b/gcc/config/i386/x86intrin.h @@ -105,6 +105,18 @@ #include <prfchwintrin.h> #endif +#ifdef __FXSR__ +#include <fxsrintrin.h> +#endif + +#ifdef __XSAVE__ +#include <xsaveintrin.h> +#endif + +#ifdef __XSAVEOPT__ +#include <xsaveoptintrin.h> +#endif + #include <adxintrin.h> #endif /* _X86INTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/xsaveintrin.h b/gcc/config/i386/xsaveintrin.h new file mode 100644 index 00000000000..0acae2720b1 --- /dev/null +++ b/gcc/config/i386/xsaveintrin.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2012 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 && !defined _IMMINTRIN_H_INCLUDED */ +/* # error "Never use <xsaveintrin.h> directly; include <x86intrin.h> instead." */ +/* #endif */ + +#ifndef _XSAVEINTRIN_H_INCLUDED +#define _XSAVEINTRIN_H_INCLUDED + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xsave (void *__P, long long __M) +{ + return __builtin_ia32_xsave (__P, __M); +} + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xrstor (void *__P, long long __M) +{ + return __builtin_ia32_xrstor (__P, __M); +} + +#ifdef __x86_64__ +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xsave64 (void *__P, long long __M) +{ + return __builtin_ia32_xsave64 (__P, __M); +} + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xrstor64 (void *__P, long long __M) +{ + return __builtin_ia32_xrstor64 (__P, __M); +} +#endif + +#endif /* _XSAVEINTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/xsaveoptintrin.h b/gcc/config/i386/xsaveoptintrin.h new file mode 100644 index 00000000000..cc962a16966 --- /dev/null +++ b/gcc/config/i386/xsaveoptintrin.h @@ -0,0 +1,47 @@ +/* Copyright (C) 2012 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 && !defined _IMMINTRIN_H_INCLUDED */ +/* # error "Never use <xsaveoptintrin.h> directly; include <x86intrin.h> instead." */ +/* #endif */ + +#ifndef _XSAVEOPTINTRIN_H_INCLUDED +#define _XSAVEOPTINTRIN_H_INCLUDED + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xsaveopt (void *__P, long long __M) +{ + return __builtin_ia32_xsaveopt (__P, __M); +} + +#ifdef __x86_64__ +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_xsaveopt64 (void *__P, long long __M) +{ + return __builtin_ia32_xsaveopt64 (__P, __M); +} +#endif + +#endif /* _XSAVEOPTINTRIN_H_INCLUDED */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e4ae2b8fca0..918af7526fe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,23 @@ +2012-10-26 Alexander Ivchenko <alexander.ivchenko@intel.com> + + * gcc.target/i386/fxsave-1.c: New. + * gcc.target/i386/fxsave64-1.c: Ditto. + * gcc.target/i386/fxrstor-1.c: Ditto. + * gcc.target/i386/fxrstor64-1.c: Ditto. + * gcc.target/i386/xsave-1.c: Ditto. + * gcc.target/i386/xsave64-1.c: Ditto. + * gcc.target/i386/xrstor-1.c: Ditto. + * gcc.target/i386/xrstor64-1.c: Ditto. + * gcc.target/i386/xsaveopt-1.c: Ditto. + * gcc.target/i386/xsaveopt64-1.c: Ditto. + * gcc.target/i386/sse-12.c: Add -mfxsr, -mxsaveopt. + * gcc.target/i386/sse-13.c: Ditto. + * gcc.target/i386/sse-14.c: Ditto. + * gcc.target/i386/sse-22.c: Ditto. + * gcc.target/i386/sse-23.c: Ditto. + * g++.dg/other/i386-2.C: Ditto. + * g++.dg/other/i386-3.C: Ditto. + 2012-10-25 Jan Hubicka <jh@suse.cz> * gcc.dg/tree-ssa/cunroll-4.c: Update; we now remove the loop diff --git a/gcc/testsuite/g++.dg/other/i386-2.C b/gcc/testsuite/g++.dg/other/i386-2.C index 197497fcfe9..67dea2aa804 100644 --- a/gcc/testsuite/g++.dg/other/i386-2.C +++ b/gcc/testsuite/g++.dg/other/i386-2.C @@ -1,5 +1,5 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx" } */ +/* { dg-options "-O -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, diff --git a/gcc/testsuite/g++.dg/other/i386-3.C b/gcc/testsuite/g++.dg/other/i386-3.C index 780731e0358..8b86785e8c2 100644 --- a/gcc/testsuite/g++.dg/other/i386-3.C +++ b/gcc/testsuite/g++.dg/other/i386-3.C @@ -1,5 +1,5 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ -/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx" } */ +/* { dg-options "-O -fkeep-inline-functions -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt" } */ /* Test that {,x,e,p,t,s,w,a,b,i}mmintrin.h, mm3dnow.h, fma4intrin.h, xopintrin.h, abmintrin.h, bmiintrin.h, tbmintrin.h, lwpintrin.h, diff --git a/gcc/testsuite/gcc.target/i386/fxrstor-1.c b/gcc/testsuite/gcc.target/i386/fxrstor-1.c new file mode 100644 index 00000000000..0e1ca191f5e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/fxrstor-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-mfxsr -O2" } */ +/* { dg-final { scan-assembler "fxrstor\[ \\t\]" } } */ + +#include <x86intrin.h> + +void extern +fxsave_test (void) +{ + char fxsave_region [512] __attribute__((aligned(16))); + _fxrstor (fxsave_region); +} diff --git a/gcc/testsuite/gcc.target/i386/fxrstor64-1.c b/gcc/testsuite/gcc.target/i386/fxrstor64-1.c new file mode 100644 index 00000000000..fbdb1f6fef8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/fxrstor64-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mfxsr -O2" } */ +/* { dg-final { scan-assembler "fxrstor64\[ \\t\]" } } */ + +#include <x86intrin.h> + +void extern +fxsave_test (void) +{ + char fxsave_region [512] __attribute__((aligned(16))); + _fxrstor64 (fxsave_region); +} diff --git a/gcc/testsuite/gcc.target/i386/fxsave-1.c b/gcc/testsuite/gcc.target/i386/fxsave-1.c new file mode 100644 index 00000000000..567af8d0e44 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/fxsave-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-mfxsr -O2" } */ +/* { dg-final { scan-assembler "fxsave\[ \\t\]" } } */ + +#include <x86intrin.h> + +void extern +fxsave_test (void) +{ + char fxsave_region [512] __attribute__((aligned(16))); + _fxsave (fxsave_region); +} diff --git a/gcc/testsuite/gcc.target/i386/fxsave64-1.c b/gcc/testsuite/gcc.target/i386/fxsave64-1.c new file mode 100644 index 00000000000..317548ad674 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/fxsave64-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mfxsr -O2" } */ +/* { dg-final { scan-assembler "fxsave64\[ \\t\]" } } */ + +#include <x86intrin.h> + +void extern +fxsave_test (void) +{ + char fxsave_region [512] __attribute__((aligned(16))); + _fxsave64 (fxsave_region); +} diff --git a/gcc/testsuite/gcc.target/i386/sse-12.c b/gcc/testsuite/gcc.target/i386/sse-12.c index 0d78a0c84dc..c1c5745ef0b 100644 --- a/gcc/testsuite/gcc.target/i386/sse-12.c +++ b/gcc/testsuite/gcc.target/i386/sse-12.c @@ -3,7 +3,7 @@ popcntintrin.h and mm_malloc.h are usable with -O -std=c89 -pedantic-errors. */ /* { dg-do compile } */ -/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx" } */ +/* { dg-options "-O -std=c89 -pedantic-errors -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt" } */ #include <x86intrin.h> diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c index 4c575baaf78..1d777d12e4f 100644 --- a/gcc/testsuite/gcc.target/i386/sse-13.c +++ b/gcc/testsuite/gcc.target/i386/sse-13.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx" } */ +/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt" } */ #include <mm_malloc.h> diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c index c8c13cecb53..331be0e1987 100644 --- a/gcc/testsuite/gcc.target/i386/sse-14.c +++ b/gcc/testsuite/gcc.target/i386/sse-14.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx" } */ +/* { dg-options "-O0 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt" } */ #include <mm_malloc.h> diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c index ec832552874..8e4c4bd3ebd 100644 --- a/gcc/testsuite/gcc.target/i386/sse-22.c +++ b/gcc/testsuite/gcc.target/i386/sse-22.c @@ -50,7 +50,7 @@ #ifndef DIFFERENT_PRAGMAS -#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx") +#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,rtm,rdseed,prfchw,adx,fxsr,xsaveopt") #endif /* Following intrinsics require immediate arguments. They @@ -264,7 +264,7 @@ test_2 (_mm_clmulepi64_si128, __m128i, __m128i, __m128i, 1) /* x86intrin.h (FMA4/XOP/LWP/BMI/BMI2/TBM/LZCNT/FMA). */ #ifdef DIFFERENT_PRAGMAS -#pragma GCC target ("fma4,xop,lwp,bmi,bmi2,tbm,lzcnt,fma,rdseed,prfchw,adx") +#pragma GCC target ("fma4,xop,lwp,bmi,bmi2,tbm,lzcnt,fma,rdseed,prfchw,adx,fxsr,xsaveopt") #endif #include <x86intrin.h> /* xopintrin.h */ diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c index f046ef643b5..069f8e7cb80 100644 --- a/gcc/testsuite/gcc.target/i386/sse-23.c +++ b/gcc/testsuite/gcc.target/i386/sse-23.c @@ -183,7 +183,7 @@ /* rtmintrin.h */ #define __builtin_ia32_xabort(M) __builtin_ia32_xabort(1) -#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx") +#pragma GCC target ("sse4a,3dnow,avx,avx2,fma4,xop,aes,pclmul,popcnt,abm,lzcnt,bmi,bmi2,tbm,lwp,fsgsbase,rdrnd,f16c,fma,rtm,rdseed,prfchw,adx,fxsr,xsaveopt") #include <wmmintrin.h> #include <smmintrin.h> #include <mm3dnow.h> diff --git a/gcc/testsuite/gcc.target/i386/xrstor-1.c b/gcc/testsuite/gcc.target/i386/xrstor-1.c new file mode 100644 index 00000000000..3e701394890 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xrstor-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx -O2" } */ +/* { dg-final { scan-assembler "xrstor\[ \\t\]" } } */ + +#include <x86intrin.h> + +void extern +xsave_test (void) +{ + char xsave_region [512] __attribute__((aligned(64))); + _xrstor (xsave_region, ((long long) 0xA0000000F)); +} diff --git a/gcc/testsuite/gcc.target/i386/xrstor64-1.c b/gcc/testsuite/gcc.target/i386/xrstor64-1.c new file mode 100644 index 00000000000..3cf2a66cc95 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xrstor64-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mxsave -O2" } */ +/* { dg-final { scan-assembler "xrstor64\[ \\t\]" } } */ + +#include <x86intrin.h> + +void extern +xsave_test (void) +{ + char xsave_region [512] __attribute__((aligned(64))); + _xrstor64 (xsave_region, ((long long) 0xA0000000F)); +} diff --git a/gcc/testsuite/gcc.target/i386/xsave-1.c b/gcc/testsuite/gcc.target/i386/xsave-1.c new file mode 100644 index 00000000000..9eee5973921 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xsave-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-mxsave -O2" } */ +/* { dg-final { scan-assembler "xsave\[ \\t\]" } } */ + +#include <x86intrin.h> + +void extern +xsave_test (void) +{ + char xsave_region [512] __attribute__((aligned(64))); + _xsave (xsave_region, ((long long) 0xA0000000F)); +} diff --git a/gcc/testsuite/gcc.target/i386/xsave64-1.c b/gcc/testsuite/gcc.target/i386/xsave64-1.c new file mode 100644 index 00000000000..661da9171c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xsave64-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mxsave -O2" } */ +/* { dg-final { scan-assembler "xsave64\[ \\t\]" } } */ + +#include <x86intrin.h> + +void extern +xsave_test (void) +{ + char xsave_region [512] __attribute__((aligned(64))); + _xsave64 (xsave_region, ((long long) 0xA0000000F)); +} diff --git a/gcc/testsuite/gcc.target/i386/xsaveopt-1.c b/gcc/testsuite/gcc.target/i386/xsaveopt-1.c new file mode 100644 index 00000000000..b08a50a2340 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xsaveopt-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-mxsaveopt -O2" } */ +/* { dg-final { scan-assembler "xsaveopt\[ \\t\]" } } */ + +#include <x86intrin.h> + +void extern +xsave_test (void) +{ + char xsaveopt_region [512] __attribute__((aligned(64))); + _xsaveopt (xsaveopt_region, ((long long) 0xA0000000F)); +} diff --git a/gcc/testsuite/gcc.target/i386/xsaveopt64-1.c b/gcc/testsuite/gcc.target/i386/xsaveopt64-1.c new file mode 100644 index 00000000000..f7864fe3999 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/xsaveopt64-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mxsaveopt -O2" } */ +/* { dg-final { scan-assembler "xsaveopt64\[ \\t\]" } } */ + +#include <x86intrin.h> + +void extern +xsave_test (void) +{ + char xsaveopt_region [512] __attribute__((aligned(64))); + _xsaveopt64 (xsaveopt_region, ((long long) 0xA0000000F)); +} |