aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386-options.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386-options.cc')
-rw-r--r--gcc/config/i386/i386-options.cc459
1 files changed, 199 insertions, 260 deletions
diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
index a9fac01..abb5dd7 100644
--- a/gcc/config/i386/i386-options.cc
+++ b/gcc/config/i386/i386-options.cc
@@ -259,9 +259,7 @@ static struct ix86_target_opts isa2_opts[] =
{ "-msm3", OPTION_MASK_ISA2_SM3 },
{ "-msha512", OPTION_MASK_ISA2_SHA512 },
{ "-msm4", OPTION_MASK_ISA2_SM4 },
- { "-mevex512", OPTION_MASK_ISA2_EVEX512 },
{ "-musermsr", OPTION_MASK_ISA2_USER_MSR },
- { "-mavx10.1-256", OPTION_MASK_ISA2_AVX10_1_256 },
{ "-mavx10.1", OPTION_MASK_ISA2_AVX10_1 },
{ "-mavx10.2", OPTION_MASK_ISA2_AVX10_2 },
{ "-mamx-avx512", OPTION_MASK_ISA2_AMX_AVX512 },
@@ -713,8 +711,6 @@ ix86_function_specific_save (struct cl_target_option *ptr,
ptr->x_ix86_apx_features = opts->x_ix86_apx_features;
ptr->x_ix86_isa_flags_explicit = opts->x_ix86_isa_flags_explicit;
ptr->x_ix86_isa_flags2_explicit = opts->x_ix86_isa_flags2_explicit;
- ptr->x_ix86_no_avx512_explicit = opts->x_ix86_no_avx512_explicit;
- ptr->x_ix86_no_avx10_1_explicit = opts->x_ix86_no_avx10_1_explicit;
ptr->x_recip_mask_explicit = opts->x_recip_mask_explicit;
ptr->x_ix86_arch_string = opts->x_ix86_arch_string;
ptr->x_ix86_tune_string = opts->x_ix86_tune_string;
@@ -764,63 +760,63 @@ static unsigned HOST_WIDE_INT initial_ix86_arch_features[X86_ARCH_LAST] = {
/* This table must be in sync with enum processor_type in i386.h. */
static const struct processor_costs *processor_cost_table[] =
{
- &generic_cost,
- &i386_cost,
- &i486_cost,
- &pentium_cost,
- &lakemont_cost,
- &pentiumpro_cost,
- &pentium4_cost,
- &nocona_cost,
- &core_cost,
- &core_cost,
- &core_cost,
- &core_cost,
- &atom_cost,
- &slm_cost,
- &slm_cost,
- &slm_cost,
- &tremont_cost,
- &alderlake_cost,
- &alderlake_cost,
- &alderlake_cost,
- &skylake_cost,
- &skylake_cost,
- &icelake_cost,
- &icelake_cost,
- &icelake_cost,
- &skylake_cost,
- &icelake_cost,
- &skylake_cost,
- &icelake_cost,
- &alderlake_cost,
- &icelake_cost,
- &icelake_cost,
- &icelake_cost,
- &alderlake_cost,
- &alderlake_cost,
- &alderlake_cost,
- &icelake_cost,
- &intel_cost,
- &lujiazui_cost,
- &yongfeng_cost,
- &shijidadao_cost,
- &geode_cost,
- &k6_cost,
- &athlon_cost,
- &k8_cost,
- &amdfam10_cost,
- &bdver_cost,
- &bdver_cost,
- &bdver_cost,
- &bdver_cost,
- &btver1_cost,
- &btver2_cost,
- &znver1_cost,
- &znver2_cost,
- &znver3_cost,
- &znver4_cost,
- &znver5_cost
+ &generic_cost, /* PROCESSOR_GENERIC. */
+ &i386_cost, /* PROCESSOR_I386. */
+ &i486_cost, /* PROCESSOR_I486. */
+ &pentium_cost, /* PROCESSOR_PENTIUM. */
+ &lakemont_cost, /* PROCESSOR_LAKEMONT. */
+ &pentiumpro_cost, /* PROCESSOR_PENTIUMPRO. */
+ &pentium4_cost, /* PROCESSOR_PENTIUM4. */
+ &nocona_cost, /* PROCESSOR_NOCONA. */
+ &core_cost, /* PROCESSOR_CORE2. */
+ &core_cost, /* PROCESSOR_NEHALEM. */
+ &core_cost, /* PROCESSOR_SANDYBRIDGE. */
+ &core_cost, /* PROCESSOR_HASWELL. */
+ &atom_cost, /* PROCESSOR_BONNELL. */
+ &slm_cost, /* PROCESSOR_SILVERMONT. */
+ &slm_cost, /* PROCESSOR_GOLDMONT. */
+ &slm_cost, /* PROCESSOR_GOLDMONT_PLUS. */
+ &tremont_cost, /* PROCESSOR_TREMONT. */
+ &alderlake_cost, /* PROCESSOR_SIERRAFOREST. */
+ &alderlake_cost, /* PROCESSOR_GRANDRIDGE. */
+ &alderlake_cost, /* PROCESSOR_CLEARWATERFOREST. */
+ &skylake_cost, /* PROCESSOR_SKYLAKE. */
+ &skylake_cost, /* PROCESSOR_SKYLAKE_AVX512. */
+ &icelake_cost, /* PROCESSOR_CANNONLAKE. */
+ &icelake_cost, /* PROCESSOR_ICELAKE_CLIENT. */
+ &icelake_cost, /* PROCESSOR_ICELAKE_SERVER. */
+ &skylake_cost, /* PROCESSOR_CASCADELAKE. */
+ &icelake_cost, /* PROCESSOR_TIGERLAKE. */
+ &skylake_cost, /* PROCESSOR_COOPERLAKE. */
+ &icelake_cost, /* PROCESSOR_SAPPHIRERAPIDS. */
+ &alderlake_cost, /* PROCESSOR_ALDERLAKE. */
+ &icelake_cost, /* PROCESSOR_ROCKETLAKE. */
+ &icelake_cost, /* PROCESSOR_GRANITERAPIDS. */
+ &icelake_cost, /* PROCESSOR_GRANITERAPIDS_D. */
+ &alderlake_cost, /* PROCESSOR_ARROWLAKE. */
+ &alderlake_cost, /* PROCESSOR_ARROWLAKE_S. */
+ &alderlake_cost, /* PROCESSOR_PANTHERLAKE. */
+ &icelake_cost, /* PROCESSOR_DIAMONDRAPIDS. */
+ &alderlake_cost, /* PROCESSOR_INTEL. */
+ &lujiazui_cost, /* PROCESSOR_LUJIAZUI. */
+ &yongfeng_cost, /* PROCESSOR_YONGFENG. */
+ &shijidadao_cost, /* PROCESSOR_SHIJIDADAO. */
+ &geode_cost, /* PROCESSOR_GEODE. */
+ &k6_cost, /* PROCESSOR_K6. */
+ &athlon_cost, /* PROCESSOR_ATHLON. */
+ &k8_cost, /* PROCESSOR_K8. */
+ &amdfam10_cost, /* PROCESSOR_AMDFAM10. */
+ &bdver_cost, /* PROCESSOR_BDVER1. */
+ &bdver_cost, /* PROCESSOR_BDVER2. */
+ &bdver_cost, /* PROCESSOR_BDVER3. */
+ &bdver_cost, /* PROCESSOR_BDVER4. */
+ &btver1_cost, /* PROCESSOR_BTVER1. */
+ &btver2_cost, /* PROCESSOR_BTVER2. */
+ &znver1_cost, /* PROCESSOR_ZNVER1. */
+ &znver2_cost, /* PROCESSOR_ZNVER2. */
+ &znver3_cost, /* PROCESSOR_ZNVER3. */
+ &znver4_cost, /* PROCESSOR_ZNVER4. */
+ &znver5_cost /* PROCESSOR_ZNVER5. */
};
/* Guarantee that the array is aligned with enum processor_type. */
@@ -858,8 +854,6 @@ ix86_function_specific_restore (struct gcc_options *opts,
opts->x_ix86_apx_features = ptr->x_ix86_apx_features;
opts->x_ix86_isa_flags_explicit = ptr->x_ix86_isa_flags_explicit;
opts->x_ix86_isa_flags2_explicit = ptr->x_ix86_isa_flags2_explicit;
- opts->x_ix86_no_avx512_explicit = ptr->x_ix86_no_avx512_explicit;
- opts->x_ix86_no_avx10_1_explicit = ptr->x_ix86_no_avx10_1_explicit;
opts->x_recip_mask_explicit = ptr->x_recip_mask_explicit;
opts->x_ix86_arch_string = ptr->x_ix86_arch_string;
opts->x_ix86_tune_string = ptr->x_ix86_tune_string;
@@ -1131,11 +1125,8 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
IX86_ATTR_ISA ("sha512", OPT_msha512),
IX86_ATTR_ISA ("sm4", OPT_msm4),
IX86_ATTR_ISA ("apxf", OPT_mapxf),
- IX86_ATTR_ISA ("evex512", OPT_mevex512),
IX86_ATTR_ISA ("usermsr", OPT_musermsr),
- IX86_ATTR_ISA ("avx10.1-256", OPT_mavx10_1_256),
IX86_ATTR_ISA ("avx10.1", OPT_mavx10_1),
- IX86_ATTR_ISA ("avx10.1-512", OPT_mavx10_1),
IX86_ATTR_ISA ("avx10.2", OPT_mavx10_2),
IX86_ATTR_ISA ("amx-avx512", OPT_mamx_avx512),
IX86_ATTR_ISA ("amx-tf32", OPT_mamx_tf32),
@@ -1181,6 +1172,10 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
OPT_mrecip,
MASK_RECIP),
+ IX86_ATTR_YES ("80387",
+ OPT_m80387,
+ MASK_80387),
+
IX86_ATTR_IX86_YES ("general-regs-only",
OPT_mgeneral_regs_only,
OPTION_MASK_GENERAL_REGS_ONLY),
@@ -1271,13 +1266,6 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
}
}
- /* Fixup -msse4 which is RejectNegative to -mno-sse4 when negated. */
- if (opt == OPT_msse4 && !opt_set_p)
- {
- opt = OPT_mno_sse4;
- opt_set_p = true;
- }
-
/* Process the option. */
if (opt == N_OPTS)
{
@@ -1297,6 +1285,8 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
else if (type == ix86_opt_yes || type == ix86_opt_no)
{
+ opts_set->x_target_flags |= mask;
+
if (type == ix86_opt_no)
opt_set_p = !opt_set_p;
@@ -1378,7 +1368,9 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
arg_ok = opt_enum_arg_to_value (opt, p + opt_len, &value, CL_TARGET);
if (arg_ok)
set_option (opts, enum_opts_set, opt, value,
- p + opt_len, DK_UNSPECIFIED, input_location,
+ p + opt_len,
+ static_cast<int> (diagnostics::kind::unspecified),
+ input_location,
global_dc);
else
{
@@ -1436,18 +1428,6 @@ ix86_valid_target_attribute_tree (tree fndecl, tree args,
target_clone_attr))
return error_mark_node;
- /* AVX10.1-256 will enable only 256 bit AVX512F features by setting all
- AVX512 related ISA flags and not setting EVEX512. When it is used
- with avx512 related function attribute, we need to enable 512 bit to
- align with the command line behavior. Manually set EVEX512 for this
- scenario. */
- if ((def->x_ix86_isa_flags2 & OPTION_MASK_ISA2_AVX10_1_256)
- && (opts->x_ix86_isa_flags & OPTION_MASK_ISA_AVX512F)
- && (opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX512F)
- && !(def->x_ix86_isa_flags2_explicit & OPTION_MASK_ISA2_EVEX512)
- && !(opts->x_ix86_isa_flags2_explicit & OPTION_MASK_ISA2_EVEX512))
- opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_EVEX512;
-
/* If the changed options are different from the default, rerun
ix86_option_override_internal, and then save the options away.
The string options are attribute options, and will be undone
@@ -1458,10 +1438,7 @@ ix86_valid_target_attribute_tree (tree fndecl, tree args,
|| option_strings[IX86_FUNCTION_SPECIFIC_ARCH]
|| option_strings[IX86_FUNCTION_SPECIFIC_TUNE]
|| enum_opts_set.x_ix86_fpmath
- || enum_opts_set.x_prefer_vector_width_type
- || (!(def->x_ix86_isa_flags2_explicit & OPTION_MASK_ISA2_AVX10_1_256)
- && (opts->x_ix86_isa_flags2_explicit
- & OPTION_MASK_ISA2_AVX10_1_256)))
+ || enum_opts_set.x_prefer_vector_width_type)
{
/* If we are using the default tune= or arch=, undo the string assigned,
and use the default. */
@@ -2025,7 +2002,7 @@ ix86_option_override_internal (bool main_args_p,
struct gcc_options *opts_set)
{
unsigned int i;
- unsigned HOST_WIDE_INT ix86_arch_mask, avx512_isa_flags, avx512_isa_flags2;
+ unsigned HOST_WIDE_INT ix86_arch_mask;
const bool ix86_tune_specified = (opts->x_ix86_tune_string != NULL);
/* -mrecip options. */
@@ -2044,15 +2021,6 @@ ix86_option_override_internal (bool main_args_p,
{ "vec-sqrt", RECIP_MASK_VEC_SQRT },
};
- avx512_isa_flags = OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX512CD
- | OPTION_MASK_ISA_AVX512DQ | OPTION_MASK_ISA_AVX512BW
- | OPTION_MASK_ISA_AVX512VL | OPTION_MASK_ISA_AVX512IFMA
- | OPTION_MASK_ISA_AVX512VBMI | OPTION_MASK_ISA_AVX512VBMI2
- | OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VPOPCNTDQ
- | OPTION_MASK_ISA_AVX512BITALG;
- avx512_isa_flags2 = OPTION_MASK_ISA2_AVX512FP16
- | OPTION_MASK_ISA2_AVX512BF16;
-
/* Turn off both OPTION_MASK_ABI_64 and OPTION_MASK_ABI_X32 if
TARGET_64BIT_DEFAULT is true and TARGET_64BIT is false. */
if (TARGET_64BIT_DEFAULT && !TARGET_64BIT_P (opts->x_ix86_isa_flags))
@@ -2674,107 +2642,6 @@ ix86_option_override_internal (bool main_args_p,
&= ~((OPTION_MASK_ISA_BMI | OPTION_MASK_ISA_BMI2 | OPTION_MASK_ISA_TBM)
& ~opts->x_ix86_isa_flags_explicit);
- /* Emit a warning if AVX10.1 options is used with AVX512/EVEX512 options except
- for the following option combinations:
- 1. Both AVX10.1-512 and AVX512 with 512 bit vector width are enabled with no
- explicit disable on other AVX512 features.
- 2. Both AVX10.1-256 and AVX512 w/o 512 bit vector width are enabled with no
- explicit disable on other AVX512 features.
- 3. Both AVX10.1 and AVX512 are disabled. */
- if (TARGET_AVX10_1_P (opts->x_ix86_isa_flags2))
- {
- if (opts->x_ix86_no_avx512_explicit
- && (((~(avx512_isa_flags & opts->x_ix86_isa_flags)
- & (avx512_isa_flags & opts->x_ix86_isa_flags_explicit)))
- || ((~((avx512_isa_flags2 | OPTION_MASK_ISA2_EVEX512)
- & opts->x_ix86_isa_flags2)
- & ((avx512_isa_flags2 | OPTION_MASK_ISA2_EVEX512)
- & opts->x_ix86_isa_flags2_explicit)))))
- warning (0, "%<-mno-evex512%> or %<-mno-avx512XXX%> cannot disable "
- "AVX10 instructions when AVX10.1-512 is available in GCC 15, "
- "behavior will change to it will disable that part of "
- "AVX512 instructions since GCC 16");
- }
- else if (TARGET_AVX10_1_256_P (opts->x_ix86_isa_flags2))
- {
- if (TARGET_EVEX512_P (opts->x_ix86_isa_flags2)
- && (OPTION_MASK_ISA2_EVEX512 & opts->x_ix86_isa_flags2_explicit))
- {
- if (!TARGET_AVX512F_P (opts->x_ix86_isa_flags)
- || !(OPTION_MASK_ISA_AVX512F & opts->x_ix86_isa_flags_explicit))
- {
- /* We should not emit 512 bit instructions under AVX10.1-256
- when EVEX512 is enabled w/o any AVX512 features enabled.
- Disable EVEX512 bit for this. */
- warning (0, "Using %<-mevex512%> without any AVX512 features "
- "enabled together with AVX10.1 only will not enable "
- "any AVX512 or AVX10.1-512 features, using 256 as "
- "max vector size");
- opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_EVEX512;
- }
- else
- warning (0, "Vector size conflicts between AVX10.1 and AVX512, "
- "using 512 as max vector size");
- }
- else if (TARGET_AVX512F_P (opts->x_ix86_isa_flags)
- && (opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX512F)
- && !(OPTION_MASK_ISA2_EVEX512
- & opts->x_ix86_isa_flags2_explicit))
- warning (0, "Vector size conflicts between AVX10.1 and AVX512, using "
- "512 as max vector size");
- else if (opts->x_ix86_no_avx512_explicit
- && (((~(avx512_isa_flags & opts->x_ix86_isa_flags)
- & (avx512_isa_flags & opts->x_ix86_isa_flags_explicit)))
- || ((~(avx512_isa_flags2 & opts->x_ix86_isa_flags2)
- & (avx512_isa_flags2
- & opts->x_ix86_isa_flags2_explicit)))))
- warning (0, "%<-mno-avx512XXX%> cannot disable AVX10 instructions "
- "when AVX10 is available in GCC 15, behavior will change "
- "to it will disable that part of AVX512 instructions since "
- "GCC 16");
- }
- else if (TARGET_AVX512F_P (opts->x_ix86_isa_flags)
- && (OPTION_MASK_ISA_AVX512F & opts->x_ix86_isa_flags_explicit))
- {
- if (opts->x_ix86_no_avx10_1_explicit
- && ((OPTION_MASK_ISA2_AVX10_1_256 | OPTION_MASK_ISA2_AVX10_1)
- & opts->x_ix86_isa_flags2_explicit))
- {
- warning (0, "%<-mno-avx10.1-256, -mno-avx10.1-512%> cannot disable "
- "AVX512 instructions when %<-mavx512XXX%> in GCC 15, "
- "behavior will change to it will disable all the "
- "instructions in GCC 16");
- /* Reset those unset AVX512 flags set by AVX10 options when AVX10 is
- disabled. */
- if (OPTION_MASK_ISA2_AVX10_1_256 & opts->x_ix86_isa_flags2_explicit)
- {
- opts->x_ix86_isa_flags = (~avx512_isa_flags
- & opts->x_ix86_isa_flags)
- | (avx512_isa_flags & opts->x_ix86_isa_flags
- & opts->x_ix86_isa_flags_explicit);
- opts->x_ix86_isa_flags2 = (~avx512_isa_flags2
- & opts->x_ix86_isa_flags2)
- | (avx512_isa_flags2 & opts->x_ix86_isa_flags2
- & opts->x_ix86_isa_flags2_explicit);
- }
- }
- }
-
- /* Set EVEX512 if one of the following conditions meets:
- 1. AVX512 is enabled while EVEX512 is not explicitly set/unset.
- 2. AVX10.1-512 is enabled. */
- if (TARGET_AVX10_1_P (opts->x_ix86_isa_flags2)
- || (TARGET_AVX512F_P (opts->x_ix86_isa_flags)
- && !(opts->x_ix86_isa_flags2_explicit & OPTION_MASK_ISA2_EVEX512)))
- opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_EVEX512;
-
- /* Enable all AVX512 related ISAs when AVX10.1 is enabled. */
- if (TARGET_AVX10_1_256_P (opts->x_ix86_isa_flags2))
- {
- opts->x_ix86_isa_flags |= avx512_isa_flags;
- opts->x_ix86_isa_flags2 |= avx512_isa_flags2;
- }
-
/* Validate -mpreferred-stack-boundary= value or default it to
PREFERRED_STACK_BOUNDARY_DEFAULT. */
ix86_preferred_stack_boundary = PREFERRED_STACK_BOUNDARY_DEFAULT;
@@ -2828,8 +2695,8 @@ ix86_option_override_internal (bool main_args_p,
if (flag_nop_mcount)
error ("%<-mnop-mcount%> is not compatible with this target");
#endif
- if (flag_nop_mcount && flag_pic)
- error ("%<-mnop-mcount%> is not implemented for %<-fPIC%>");
+ if (flag_nop_mcount && flag_pic && !flag_plt)
+ error ("%<-mnop-mcount%> is not implemented for %<-fno-plt%>");
/* Accept -msseregparm only if at least SSE support is enabled. */
if (TARGET_SSEREGPARM_P (opts->x_target_flags)
@@ -2980,7 +2847,9 @@ ix86_option_override_internal (bool main_args_p,
/* Set the default value for -mfentry. */
if (!opts_set->x_flag_fentry)
- opts->x_flag_fentry = TARGET_SEH;
+ opts->x_flag_fentry = (TARGET_SEH
+ || (TARGET_64BIT_P (opts->x_ix86_isa_flags)
+ && ENABLE_X86_64_MFENTRY));
else
{
if (!TARGET_64BIT_P (opts->x_ix86_isa_flags) && opts->x_flag_pic
@@ -2991,6 +2860,17 @@ ix86_option_override_internal (bool main_args_p,
sorry ("%<-mno-fentry%> isn%'t compatible with SEH");
}
+#ifdef OPTION_GLIBC_P
+ /* -mfentry is supported only on glibc targets. */
+ if (!opts->x_flag_fentry
+ && OPTION_GLIBC_P (opts)
+ && (TARGET_64BIT_P (opts->x_ix86_isa_flags) || !opts->x_flag_pic)
+ && opts->x_flag_shrink_wrap
+ && opts->x_profile_flag)
+ warning (0, "%<-pg%> without %<-mfentry%> may be unreliable with "
+ "shrink wrapping");
+#endif
+
if (TARGET_SEH && TARGET_CALL_MS2SYSV_XLOGUES)
sorry ("%<-mcall-ms2sysv-xlogues%> isn%'t currently supported with SEH");
@@ -3049,8 +2929,7 @@ ix86_option_override_internal (bool main_args_p,
opts->x_ix86_move_max = opts->x_prefer_vector_width_type;
if (opts_set->x_ix86_move_max == PVW_NONE)
{
- if (TARGET_AVX512F_P (opts->x_ix86_isa_flags)
- && TARGET_EVEX512_P (opts->x_ix86_isa_flags2))
+ if (TARGET_AVX512F_P (opts->x_ix86_isa_flags))
opts->x_ix86_move_max = PVW_AVX512;
/* Align with vectorizer to avoid potential STLF issue. */
else if (TARGET_AVX_P (opts->x_ix86_isa_flags))
@@ -3076,8 +2955,7 @@ ix86_option_override_internal (bool main_args_p,
opts->x_ix86_store_max = opts->x_prefer_vector_width_type;
if (opts_set->x_ix86_store_max == PVW_NONE)
{
- if (TARGET_AVX512F_P (opts->x_ix86_isa_flags)
- && TARGET_EVEX512_P (opts->x_ix86_isa_flags2))
+ if (TARGET_AVX512F_P (opts->x_ix86_isa_flags))
opts->x_ix86_store_max = PVW_AVX512;
/* Align with vectorizer to avoid potential STLF issue. */
else if (TARGET_AVX_P (opts->x_ix86_isa_flags))
@@ -3374,13 +3252,13 @@ ix86_simd_clone_adjust (struct cgraph_node *node)
case 'e':
if (TARGET_PREFER_AVX256)
{
- if (!TARGET_AVX512F || !TARGET_EVEX512)
- str = "avx512f,evex512,prefer-vector-width=512";
+ if (!TARGET_AVX512F)
+ str = "avx512f,prefer-vector-width=512";
else
str = "prefer-vector-width=512";
}
- else if (!TARGET_AVX512F || !TARGET_EVEX512)
- str = "avx512f,evex512";
+ else if (!TARGET_AVX512F)
+ str = "avx512f";
break;
default:
gcc_unreachable ();
@@ -3420,19 +3298,21 @@ ix86_set_func_type (tree fndecl)
interrupt function in this case. */
enum call_saved_registers_type no_callee_saved_registers
= TYPE_DEFAULT_CALL_SAVED_REGISTERS;
- if (lookup_attribute ("no_callee_saved_registers",
- TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+ if (lookup_attribute ("preserve_none",
+ TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+ no_callee_saved_registers = TYPE_PRESERVE_NONE;
+ else if ((lookup_attribute ("no_callee_saved_registers",
+ TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+ || (ix86_noreturn_no_callee_saved_registers
+ && TREE_THIS_VOLATILE (fndecl)
+ && optimize
+ && !optimize_debug
+ && (TREE_NOTHROW (fndecl) || !flag_exceptions)
+ && !lookup_attribute ("interrupt",
+ TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))
+ && !lookup_attribute ("no_caller_saved_registers",
+ TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))))
no_callee_saved_registers = TYPE_NO_CALLEE_SAVED_REGISTERS;
- else if (ix86_noreturn_no_callee_saved_registers
- && TREE_THIS_VOLATILE (fndecl)
- && optimize
- && !optimize_debug
- && (TREE_NOTHROW (fndecl) || !flag_exceptions)
- && !lookup_attribute ("interrupt",
- TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))
- && !lookup_attribute ("no_caller_saved_registers",
- TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
- no_callee_saved_registers = TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP;
if (cfun->machine->func_type == TYPE_UNKNOWN)
{
@@ -3444,9 +3324,16 @@ ix86_set_func_type (tree fndecl)
"interrupt and naked attributes are not compatible");
if (no_callee_saved_registers)
- error_at (DECL_SOURCE_LOCATION (fndecl),
- "%qs and %qs attributes are not compatible",
- "interrupt", "no_callee_saved_registers");
+ {
+ const char *attr;
+ if (no_callee_saved_registers == TYPE_PRESERVE_NONE)
+ attr = "preserve_none";
+ else
+ attr = "no_callee_saved_registers";
+ error_at (DECL_SOURCE_LOCATION (fndecl),
+ "%qs and %qs attributes are not compatible",
+ "interrupt", attr);
+ }
int nargs = 0;
for (tree arg = DECL_ARGUMENTS (fndecl);
@@ -3468,21 +3355,13 @@ ix86_set_func_type (tree fndecl)
else
{
cfun->machine->func_type = TYPE_NORMAL;
- if (lookup_attribute ("no_caller_saved_registers",
- TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+ if (no_callee_saved_registers)
+ cfun->machine->call_saved_registers
+ = no_callee_saved_registers;
+ else if (lookup_attribute ("no_caller_saved_registers",
+ TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
cfun->machine->call_saved_registers
= TYPE_NO_CALLER_SAVED_REGISTERS;
- if (no_callee_saved_registers)
- {
- if (cfun->machine->call_saved_registers
- == TYPE_NO_CALLER_SAVED_REGISTERS)
- error_at (DECL_SOURCE_LOCATION (fndecl),
- "%qs and %qs attributes are not compatible",
- "no_caller_saved_registers",
- "no_callee_saved_registers");
- cfun->machine->call_saved_registers
- = no_callee_saved_registers;
- }
}
}
}
@@ -3671,11 +3550,25 @@ ix86_set_current_function (tree fndecl)
|| (cfun->machine->call_saved_registers
== TYPE_NO_CALLER_SAVED_REGISTERS))
{
- /* Don't allow SSE, MMX nor x87 instructions since they
- may change processor state. */
+ /* Don't allow AVX, AVX512, MMX nor x87 instructions since they
+ may change processor state. Don't allow SSE instructions in
+ exception/interrupt service routines. */
const char *isa;
if (TARGET_SSE)
- isa = "SSE";
+ {
+ if (TARGET_AVX512F)
+ isa = "AVX512";
+ else if (TARGET_AVX)
+ isa = "AVX";
+ else if (cfun->machine->func_type != TYPE_NORMAL)
+ isa = "SSE";
+ else if (TARGET_MMX)
+ isa = "MMX/3Dnow";
+ else if (TARGET_80387)
+ isa = "80387";
+ else
+ isa = NULL;
+ }
else if (TARGET_MMX)
isa = "MMX/3Dnow";
else if (TARGET_80387)
@@ -3732,6 +3625,18 @@ ix86_handle_cconv_attribute (tree *node, tree name, tree args, int,
return NULL_TREE;
}
+ if (TARGET_64BIT)
+ {
+ /* Do not warn when emulating the MS ABI. */
+ if ((TREE_CODE (*node) != FUNCTION_TYPE
+ && TREE_CODE (*node) != METHOD_TYPE)
+ || ix86_function_type_abi (*node) != MS_ABI)
+ warning (OPT_Wattributes, "%qE attribute ignored",
+ name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
/* Can combine regparm with all attributes but fastcall, and thiscall. */
if (is_attribute_p ("regparm", name))
{
@@ -3744,7 +3649,7 @@ ix86_handle_cconv_attribute (tree *node, tree name, tree args, int,
if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
{
- error ("regparam and thiscall attributes are not compatible");
+ error ("regparm and thiscall attributes are not compatible");
}
cst = TREE_VALUE (args);
@@ -3765,19 +3670,7 @@ ix86_handle_cconv_attribute (tree *node, tree name, tree args, int,
return NULL_TREE;
}
- if (TARGET_64BIT)
- {
- /* Do not warn when emulating the MS ABI. */
- if ((TREE_CODE (*node) != FUNCTION_TYPE
- && TREE_CODE (*node) != METHOD_TYPE)
- || ix86_function_type_abi (*node) != MS_ABI)
- warning (OPT_Wattributes, "%qE attribute ignored",
- name);
- *no_add_attrs = true;
- return NULL_TREE;
- }
-
- /* Can combine fastcall with stdcall (redundant) and sseregparm. */
+ /* Can combine fastcall with sseregparm. */
if (is_attribute_p ("fastcall", name))
{
if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
@@ -3798,8 +3691,7 @@ ix86_handle_cconv_attribute (tree *node, tree name, tree args, int,
}
}
- /* Can combine stdcall with fastcall (redundant), regparm and
- sseregparm. */
+ /* Can combine stdcall with regparm and sseregparm. */
else if (is_attribute_p ("stdcall", name))
{
if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
@@ -3849,6 +3741,10 @@ ix86_handle_cconv_attribute (tree *node, tree name, tree args, int,
{
error ("cdecl and thiscall attributes are not compatible");
}
+ if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (*node)))
+ {
+ error ("regparm and thiscall attributes are not compatible");
+ }
}
/* Can combine sseregparm with all attributes. */
@@ -4100,9 +3996,50 @@ ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int,
}
static tree
-ix86_handle_call_saved_registers_attribute (tree *, tree, tree,
+ix86_handle_call_saved_registers_attribute (tree *node, tree name, tree,
int, bool *)
{
+ const char *attr1 = nullptr;
+ const char *attr2 = nullptr;
+
+ if (is_attribute_p ("no_callee_saved_registers", name))
+ {
+ /* Disallow preserve_none and no_caller_saved_registers
+ attributes. */
+ attr1 = "no_callee_saved_registers";
+ if (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (*node)))
+ attr2 = "preserve_none";
+ else if (lookup_attribute ("no_caller_saved_registers",
+ TYPE_ATTRIBUTES (*node)))
+ attr2 = "no_caller_saved_registers";
+ }
+ else if (is_attribute_p ("no_caller_saved_registers", name))
+ {
+ /* Disallow preserve_none and no_callee_saved_registers
+ attributes. */
+ attr1 = "no_caller_saved_registers";
+ if (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (*node)))
+ attr2 = "preserve_none";
+ else if (lookup_attribute ("no_callee_saved_registers",
+ TYPE_ATTRIBUTES (*node)))
+ attr2 = "no_callee_saved_registers";
+ }
+ else if (is_attribute_p ("preserve_none", name))
+ {
+ /* Disallow no_callee_saved_registers and no_caller_saved_registers
+ attributes. */
+ attr1 = "preserve_none";
+ if (lookup_attribute ("no_callee_saved_registers",
+ TYPE_ATTRIBUTES (*node)))
+ attr2 = "no_caller_saved_registers";
+ else if (lookup_attribute ("no_callee_saved_registers",
+ TYPE_ATTRIBUTES (*node)))
+ attr2 = "no_callee_saved_registers";
+ }
+
+ if (attr2)
+ error ("%qs and %qs attributes are not compatible", attr1, attr2);
+
return NULL_TREE;
}
@@ -4264,6 +4201,8 @@ static const attribute_spec ix86_gnu_attributes[] =
ix86_handle_interrupt_attribute, NULL },
{ "no_caller_saved_registers", 0, 0, false, true, true, false,
ix86_handle_call_saved_registers_attribute, NULL },
+ { "preserve_none", 0, 0, false, true, true, true,
+ ix86_handle_call_saved_registers_attribute, NULL },
{ "no_callee_saved_registers", 0, 0, false, true, true, true,
ix86_handle_call_saved_registers_attribute, NULL },
{ "naked", 0, 0, true, false, false, false,