@@ -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.
@@ -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. */
@@ -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)
@@ -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,
@@ -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