diff mbox series

[12/12] aarch64: Extend aarch64_feature_flags to 128 bits

Message ID 016dd9de-fb1c-2c3e-ecb9-ddf3620f8c47@e124511.cambridge.arm.com
State New
Headers show
Series aarch64: Extend aarch64_feature_flags to 128 bits | expand

Commit Message

Andrew Carlotti May 14, 2024, 3 p.m. UTC
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 mbox series

Patch

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