Replace the existing typedef with a new class containing two private uint64_t members.
Most of the preparatory work was carried out in previous commits. The most notable remaining changes are the addition of the get_isa_mode and with_isa_mode functions for conversion to or from aarch64_isa_mode types, and the use of a 'save' member function from within aarch64_set_asm_isa_flags, to avoid needing to expose the uint64_t members. gcc/ChangeLog: * common/config/aarch64/aarch64-common.cc (aarch64_set_asm_isa_flags): Use new flags.save function. * config/aarch64/aarch64-opts.h (class aarch64_feature_flags): New class. (aarch64_feature_flags_from_index): Update to handle 128 bits. (AARCH64_NO_FEATURES): Pass a second constructor parameter. * config/aarch64/aarch64.cc (aarch64_guard_switch_pstate_sm): Extract isa mode explicitly. (aarch64_expand_epilogue): Ditto. (aarch64_expand_call): Ditto (aarch64_set_current_function): Set/extract isa mode explicitly. * config/aarch64/aarch64.h (aarch64_get_asm_isa_flags): Use new option struct member. (aarch64_get_isa_flags): Use new option struct member. (aarch64_asm_isa_flags): Use second global variable. (aarch64_isa_flags): Ditto. (AARCH64_FL_ISA_MODES): Pass a second constructor parameter. (AARCH64_FL_DEFAULT_ISA_MODE): Ditto. (AARCH64_ISA_MODE): Extract isa mode explicitly. * config/aarch64/aarch64.opt (aarch64_asm_isa_flags_1): Add a second uint64_t for bitmask. (aarch64_isa_flags_1): Ditto. diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc index 9f583bb80456709e0028c358a1bad23ad59f20f4..a84650086ba9a1054f3ba15022567a00b7fb4313 100644 --- a/gcc/common/config/aarch64/aarch64-common.cc +++ b/gcc/common/config/aarch64/aarch64-common.cc @@ -67,18 +67,18 @@ static const struct default_options aarch_option_optimization_table[] = }; -/* Set OPTS->x_aarch64_asm_isa_flags_0 to FLAGS and update - OPTS->x_aarch64_isa_flags_0 accordingly. */ +/* Set OPTS->x_aarch64_asm_isa_flags_<0..n> to FLAGS and update + OPTS->x_aarch64_isa_flags_<0..n> accordingly. */ void aarch64_set_asm_isa_flags (gcc_options *opts, aarch64_feature_flags flags) { - opts->x_aarch64_asm_isa_flags_0 = flags; + flags.save(&opts->x_aarch64_asm_isa_flags_0, &opts->x_aarch64_asm_isa_flags_1); if (opts->x_target_flags & MASK_GENERAL_REGS_ONLY) { constexpr auto flags_mask = ~feature_deps::get_flags_off (AARCH64_FL_FP); flags &= flags_mask; } - opts->x_aarch64_isa_flags_0 = flags; + flags.save(&opts->x_aarch64_isa_flags_0, &opts->x_aarch64_isa_flags_1); } /* Implement TARGET_HANDLE_OPTION. diff --git a/gcc/config/aarch64/aarch64-opts.h b/gcc/config/aarch64/aarch64-opts.h index 80926a008aa2ed7dffa79aaa425dd3d7fc9d2581..7571385740d5271ab99bcc3380899a550788592d 100644 --- a/gcc/config/aarch64/aarch64-opts.h +++ b/gcc/config/aarch64/aarch64-opts.h @@ -25,17 +25,110 @@ #ifndef USED_FOR_TARGET typedef uint64_t aarch64_isa_mode; -typedef uint64_t aarch64_feature_flags; - constexpr unsigned int AARCH64_NUM_ISA_MODES = (0 #define DEF_AARCH64_ISA_MODE(IDENT) + 1 #include "aarch64-isa-modes.def" ); +class aarch64_feature_flags +{ +private: + uint64_t flags0; + uint64_t flags1; + +public: + constexpr aarch64_feature_flags (uint64_t flags0_m, uint64_t flags1_m) + : flags0 (flags0_m), flags1 (flags1_m) {} + aarch64_feature_flags () = default; + + void save(uint64_t *save0, uint64_t *save1) + { + *save0 = flags0; + *save1 = flags1; + } + + constexpr aarch64_isa_mode get_isa_mode () + { + return flags0 & ((1 << AARCH64_NUM_ISA_MODES) - 1); + } + + constexpr aarch64_feature_flags with_isa_mode (const aarch64_isa_mode mode) const + { + return aarch64_feature_flags ((flags0 & ~((1 << AARCH64_NUM_ISA_MODES) - 1)) | mode, + flags1); + } + + constexpr aarch64_feature_flags operator&(const aarch64_feature_flags other) const + { + return aarch64_feature_flags (flags0 & other.flags0, + flags1 & other.flags1); + } + + aarch64_feature_flags operator&=(const aarch64_feature_flags other) + { + flags0 &= other.flags0; + flags1 &= other.flags1; + return *this; + } + + constexpr aarch64_feature_flags operator|(const aarch64_feature_flags other) const + { + return aarch64_feature_flags (flags0 | other.flags0, + flags1 | other.flags1); + } + + aarch64_feature_flags operator|=(const aarch64_feature_flags other) + { + flags0 |= other.flags0; + flags1 |= other.flags1; + return *this; + } + + constexpr aarch64_feature_flags operator^(const aarch64_feature_flags other) const + { + return aarch64_feature_flags (flags0 ^ other.flags0, + flags1 ^ other.flags1); + } + + aarch64_feature_flags operator^=(const aarch64_feature_flags other) + { + flags0 ^= other.flags0; + flags1 ^= other.flags1; + return *this; + } + + constexpr aarch64_feature_flags operator~() const + { + return aarch64_feature_flags (~flags0, ~flags1); + } + + constexpr bool operator!() const + { + return !flags0 && !flags1; + } + + constexpr explicit operator bool() const + { + return ((bool) flags0) || ((bool) flags1); + } + + constexpr bool operator==(const aarch64_feature_flags other) const + { + return flags0 == other.flags0 && flags1 == other.flags1; + } + + constexpr bool operator!=(const aarch64_feature_flags other) const + { + return flags0 != other.flags0 || flags1 != other.flags1; + } + +}; + #define aarch64_feature_flags_from_index(index) \ - (aarch64_feature_flags (uint64_t (1) << index)) + (aarch64_feature_flags ((index < 64) ? uint64_t (1) << index : 0, \ + (index >= 64) ? uint64_t (1) << (index - 64) : 0)) -#define AARCH64_NO_FEATURES aarch64_feature_flags (0) +#define AARCH64_NO_FEATURES aarch64_feature_flags (0, 0) #endif /* The various cores that implement AArch64. */ diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index dd3437214e1597f03ac947a09c124ea0b04e27e8..12e5b244f28ab04cf1ecc72d2255bea179f97678 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -23,17 +23,21 @@ #define GCC_AARCH64_H #define aarch64_get_asm_isa_flags(opts) \ - (aarch64_feature_flags ((opts)->x_aarch64_asm_isa_flags_0)) + (aarch64_feature_flags ((opts)->x_aarch64_asm_isa_flags_0, \ + (opts)->x_aarch64_asm_isa_flags_1)) #define aarch64_get_isa_flags(opts) \ - (aarch64_feature_flags ((opts)->x_aarch64_isa_flags_0)) + (aarch64_feature_flags ((opts)->x_aarch64_isa_flags_0, \ + (opts)->x_aarch64_isa_flags_1)) /* Make these flags read-only so that all uses go via aarch64_set_asm_isa_flags. */ #ifdef GENERATOR_FILE #undef aarch64_asm_isa_flags -#define aarch64_asm_isa_flags (aarch64_feature_flags (aarch64_asm_isa_flags_0)) +#define aarch64_asm_isa_flags (aarch64_feature_flags (aarch64_asm_isa_flags_0,\ + aarch64_asm_isa_flags_1)) #undef aarch64_isa_flags -#define aarch64_isa_flags (aarch64_feature_flags (aarch64_isa_flags_0)) +#define aarch64_isa_flags (aarch64_feature_flags (aarch64_isa_flags_0, \ + aarch64_isa_flags_1)) #else #undef aarch64_asm_isa_flags #define aarch64_asm_isa_flags (aarch64_get_asm_isa_flags (&global_options)) @@ -209,14 +213,14 @@ constexpr auto AARCH64_ISA_MODE_SM_STATE ATTRIBUTE_UNUSED /* The mask of all ISA modes. */ constexpr auto AARCH64_FL_ISA_MODES - = (aarch64_feature_flags (1) << AARCH64_NUM_ISA_MODES) - 1; + = aarch64_feature_flags ((1 << AARCH64_NUM_ISA_MODES) - 1, 0); /* The default ISA mode, for functions with no attributes that specify something to the contrary. */ constexpr auto AARCH64_DEFAULT_ISA_MODE ATTRIBUTE_UNUSED = AARCH64_ISA_MODE_SM_OFF; constexpr auto AARCH64_FL_DEFAULT_ISA_MODE ATTRIBUTE_UNUSED - = aarch64_feature_flags (AARCH64_DEFAULT_ISA_MODE); + = aarch64_feature_flags (AARCH64_DEFAULT_ISA_MODE, 0); #endif @@ -229,7 +233,7 @@ constexpr auto AARCH64_FL_DEFAULT_ISA_MODE ATTRIBUTE_UNUSED #define AARCH64_ISA_SM_OFF (aarch64_isa_flags & AARCH64_FL_SM_OFF) #define AARCH64_ISA_SM_ON (aarch64_isa_flags & AARCH64_FL_SM_ON) #define AARCH64_ISA_ZA_ON (aarch64_isa_flags & AARCH64_FL_ZA_ON) -#define AARCH64_ISA_MODE (aarch64_isa_mode) (aarch64_isa_flags & AARCH64_FL_ISA_MODES) +#define AARCH64_ISA_MODE (aarch64_isa_flags.get_isa_mode()) #define AARCH64_ISA_V8A (aarch64_isa_flags & AARCH64_FL_V8A) #define AARCH64_ISA_V8_1A (aarch64_isa_flags & AARCH64_FL_V8_1A) #define AARCH64_ISA_CRC (aarch64_isa_flags & AARCH64_FL_CRC) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 052cf297e7672abf015a085ab357836cb3b235e4..f9efb462d75b9e536b89ef6d48bc5852a480cb8c 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -19083,7 +19083,7 @@ aarch64_set_current_function (tree fndecl) aarch64_pragma_target_parse. */ if (old_tree == new_tree && (!fndecl || aarch64_previous_fndecl) - && (aarch64_isa_mode) (isa_flags & AARCH64_FL_ISA_MODES) == new_isa_mode) + && isa_flags.get_isa_mode() == new_isa_mode) { gcc_assert (AARCH64_ISA_MODE == new_isa_mode); return; @@ -19098,11 +19098,10 @@ aarch64_set_current_function (tree fndecl) /* The ISA mode can vary based on function type attributes and function declaration attributes. Make sure that the target options correctly reflect these attributes. */ - if ((aarch64_isa_mode) (isa_flags & AARCH64_FL_ISA_MODES) != new_isa_mode) + if (isa_flags.get_isa_mode() != new_isa_mode) { - auto base_flags = (aarch64_asm_isa_flags & ~AARCH64_FL_ISA_MODES); - aarch64_set_asm_isa_flags (base_flags - | (aarch64_feature_flags) new_isa_mode); + auto new_flags = aarch64_asm_isa_flags.with_isa_mode (new_isa_mode); + aarch64_set_asm_isa_flags (new_flags); aarch64_override_options_internal (&global_options); new_tree = build_target_option_node (&global_options, diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt index 45aab49de27bdfa0fb3f67ec06c7dcf0ac242fb3..2f90f10352af75f70112d07894ab200f48b143f4 100644 --- a/gcc/config/aarch64/aarch64.opt +++ b/gcc/config/aarch64/aarch64.opt @@ -33,9 +33,15 @@ enum aarch64_arch selected_arch = aarch64_no_arch TargetVariable uint64_t aarch64_asm_isa_flags_0 = 0 +TargetVariable +uint64_t aarch64_asm_isa_flags_1 = 0 + TargetVariable uint64_t aarch64_isa_flags_0 = 0 +TargetVariable +uint64_t aarch64_isa_flags_1 = 0 + TargetVariable unsigned aarch_enable_bti = 2