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.cc384
1 files changed, 151 insertions, 233 deletions
diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
index 45aa9b4..09cb133 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),
@@ -1429,18 +1420,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
@@ -1451,10 +1430,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. */
@@ -2018,7 +1994,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. */
@@ -2037,15 +2013,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))
@@ -2667,107 +2634,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;
@@ -3042,8 +2908,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))
@@ -3069,8 +2934,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))
@@ -3367,13 +3231,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 ();
@@ -3413,19 +3277,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)
{
@@ -3437,9 +3303,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);
@@ -3461,21 +3334,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;
- }
}
}
}
@@ -3664,11 +3529,21 @@ 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
+ isa = NULL;
+ }
else if (TARGET_MMX)
isa = "MMX/3Dnow";
else if (TARGET_80387)
@@ -4093,9 +3968,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;
}
@@ -4257,6 +4173,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,