[Lldb-commits] [lldb] [lldb][AArch64][Linux] Make RegisterSetType a plain enum with bitmask values (PR #223373)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Mon Sep 14 04:27:41 PDT 2026


https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/223373

I made it a bitmask enum to make storing set validity easier, but in all the lookup functions that use RegisterSetType we only want one value of the enum. For example looking up a ptrace set number, you only ask about one set. So I have changed it to be an enum of single bit values for storage purposes, but not a BitmaskEnum.

The set dependencies used to be its own method,
I inlined that into Invalidate since it was the only user (and saves me writing a lot more static_cast).

We might have a use case for asking about many sets in future. For those cases we can add variadic
template methods.

>From aef7b86916a29bdd9bb3a67bfe45269892f357cc Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at arm.com>
Date: Fri, 14 Aug 2026 15:46:44 +0000
Subject: [PATCH] [lldb][AArch64][Linux] Make RegisterSetType a plain enum

I made it a bitmask enum to make storing set validity easier,
but in all the lookup functions that use RegisterSetType
we only want one value of it. For example looking up a ptrace
set number, you only ask about one set.

So I have changed it to be an enum of single bit values
for storage purposes, but not a BitmaskEnum.

The set dependencies used to be its own method,
I inlined that into Invalidate since it was the only
user (and saves me writing static_cast a bunch more times.

We might have a use case for asking about many sets
in future. For those cases we can add variadic
template methods.
---
 .../NativeRegisterContextLinux_arm64.cpp      | 28 +++++++++-----
 .../Linux/NativeRegisterContextLinux_arm64.h  | 38 +++++++------------
 2 files changed, 31 insertions(+), 35 deletions(-)

diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 85781be08c1bc..f9c2291c14d5d 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -70,9 +70,10 @@ using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::process_linux;
 
-NativeRegisterContextLinux_arm64::RegisterSetType
-NativeRegisterContextLinux_arm64::GetInvalidationMask(
-    const RegisterSetType set) const {
+void NativeRegisterContextLinux_arm64::Invalidate(RegisterSetType set) {
+  using Mask_t = std::underlying_type_t<RegisterSetType>;
+  Mask_t to_invalidate = 0;
+
   switch (set) {
   case RegisterSetType::FPMR:
   case RegisterSetType::GPR:
@@ -81,21 +82,28 @@ NativeRegisterContextLinux_arm64::GetInvalidationMask(
   case RegisterSetType::PAC:
   case RegisterSetType::POE:
   case RegisterSetType::TLS:
-    return set;
+    to_invalidate = static_cast<Mask_t>(set);
+    break;
   case RegisterSetType::SVE_HEADER:
   case RegisterSetType::SVE:
   case RegisterSetType::FPR:
-    return RegisterSetType::SVE_HEADER | RegisterSetType::SVE |
-           // SVE registers overlap FP registers in hardware.
-           RegisterSetType::FPR;
+    // SVE registers overlap FP registers in hardware.
+    to_invalidate = static_cast<Mask_t>(RegisterSetType::SVE_HEADER) |
+                    static_cast<Mask_t>(RegisterSetType::SVE) |
+                    static_cast<Mask_t>(RegisterSetType::FPR);
+    break;
   case RegisterSetType::ZA_HEADER:
   case RegisterSetType::ZA:
   case RegisterSetType::ZT:
     // In the Linux ptrace ABI, writes that enable ZA or ZT result in
     // both ZA and ZT being enabled.
-    return RegisterSetType::ZA_HEADER | RegisterSetType::ZA |
-           RegisterSetType::ZT;
+    to_invalidate = static_cast<Mask_t>(RegisterSetType::ZA_HEADER) |
+                    static_cast<Mask_t>(RegisterSetType::ZA) |
+                    static_cast<Mask_t>(RegisterSetType::ZT);
+    break;
   }
+
+  m_validity &= ~to_invalidate;
 }
 
 unsigned int NativeRegisterContextLinux_arm64::GetPtraceSet(
@@ -1495,7 +1503,7 @@ Status NativeRegisterContextLinux_arm64::WriteFPR() {
 }
 
 void NativeRegisterContextLinux_arm64::InvalidateAllRegisters() {
-  m_validity = static_cast<RegisterSetType>(0);
+  m_validity = 0;
 
   // Update SVE and ZA registers in case there is change in configuration.
   ConfigureRegisterContext();
diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
index 86a317c11505a..f691bb8c28f27 100644
--- a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -16,8 +16,6 @@
 #include "Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h"
 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
 
-#include "llvm/ADT/BitmaskEnum.h"
-
 #include <asm/ptrace.h>
 
 namespace lldb_private {
@@ -81,9 +79,9 @@ class NativeRegisterContextLinux_arm64
   lldb::addr_t FixWatchpointHitAddress(lldb::addr_t hit_addr) override;
 
 private:
-  // Bit mask enum used to refer to the types of registers we support. Currently
-  // used for tracking cache validity and ReadAll/WriteAllRegister data. Will
-  // be used for much more in future.
+  // Enum used to refer to the types of registers we support.
+  // Is a bitmask for storage purposes but is deliberately not a BitmaskEnum
+  // because we do not want multiple values to be passed into functions.
   enum class RegisterSetType : uint32_t {
     // General purpose registers.
     GPR = 1 << 0,
@@ -112,11 +110,7 @@ class NativeRegisterContextLinux_arm64
     GCS = 1 << 11,
     // Permission Overlay registers.
     POE = 1 << 12,
-    LLVM_MARK_AS_BITMASK_ENUM(POE),
   };
-
-  RegisterSetType m_validity = static_cast<RegisterSetType>(0);
-
   // Returns the ptrace register set number for the given register set.
   unsigned int GetPtraceSet(RegisterSetType set) const;
 
@@ -124,27 +118,21 @@ class NativeRegisterContextLinux_arm64
 
   void *GetSetBuffer(RegisterSetType set);
 
-  void MakeValid(RegisterSetType set) { m_validity |= set; }
+  std::underlying_type_t<RegisterSetType> m_validity;
 
-  [[nodiscard]] bool IsValid(RegisterSetType set) const {
-    return any(m_validity & set);
+  void MakeValid(RegisterSetType set) {
+    m_validity |= static_cast<std::underlying_type_t<RegisterSetType>>(set);
   }
 
-  /// Returns the mask of sets that would be invalidated if the given set was
-  /// invalidated. That is, the set itself and any sets that depend on it.
-  ///
-  /// If you need anything more complex such as only invalidating during certain
-  /// modes, put that logic in the function that calls Invalidate().
-  RegisterSetType GetInvalidationMask(const RegisterSetType set) const;
-
-  /// Invalidate our saved copies of the given register sets and any sets that
-  /// depend on those sets.
-  template <typename... Ts> void Invalidate(RegisterSetType first, Ts... rest) {
-    static_assert((std::is_same_v<Ts, RegisterSetType> && ...));
-    m_validity &=
-        ~(GetInvalidationMask(first) | ... | GetInvalidationMask(rest));
+  [[nodiscard]] bool IsValid(RegisterSetType set) const {
+    return m_validity &
+           static_cast<std::underlying_type_t<RegisterSetType>>(set);
   }
 
+  /// Invalidate our saved copies of the given register set and any sets that
+  /// depend on that set.
+  void Invalidate(RegisterSetType set);
+
   Status RestoreRegisters(void *buffer, const uint8_t **src, size_t len,
                           const RegisterSetType set,
                           std::function<Status()> writer);



More information about the lldb-commits mailing list