[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