Skip to content

[lldb][AArch64] Add register fields for the fpmr register #109934

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 26, 2024

Conversation

DavidSpickett
Copy link
Collaborator

The FP8 formats have a "_" in the name so that they are:

  1. Easier to read.
  2. Possible to use in register expressions if/when they are supported.

Some other bits do have defined meanings but they are not simple to name. Better that folks read the manual for those.

See this page for the full details:
https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/FPMR--Floating-point-Mode-Register

The FP8 formats have a "_" in the name so that they are:
1. Easier to read.
2. Possible to use in register expressions if/when they are supported.

Some other bits do have defined meanings but they are not
simple to name. Better that folks read the manual for those.

See this page for the full details:
https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/FPMR--Floating-point-Mode-Register
@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2024

@llvm/pr-subscribers-lldb

Author: David Spickett (DavidSpickett)

Changes

The FP8 formats have a "_" in the name so that they are:

  1. Easier to read.
  2. Possible to use in register expressions if/when they are supported.

Some other bits do have defined meanings but they are not simple to name. Better that folks read the manual for those.

See this page for the full details:
https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/FPMR--Floating-point-Mode-Register


Full diff: https://github.com/llvm/llvm-project/pull/109934.diff

3 Files Affected:

  • (modified) lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp (+24)
  • (modified) lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h (+3-1)
  • (modified) lldb/test/API/linux/aarch64/fpmr/TestAArch64LinuxFPMR.py (+5)
diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
index 7c8dba3680938d..72ced42a158233 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.cpp
@@ -23,9 +23,33 @@
 #define HWCAP2_AFP (1ULL << 20)
 #define HWCAP2_SME (1ULL << 23)
 #define HWCAP2_EBF16 (1ULL << 32)
+#define HWCAP2_FPMR (1UL << 48)
 
 using namespace lldb_private;
 
+Arm64RegisterFlagsDetector::Fields
+Arm64RegisterFlagsDetector::DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2) {
+  (void)hwcap;
+
+  if (!(hwcap2 & HWCAP2_FPMR))
+    return {};
+
+  static const FieldEnum fp8_format_enum("fp8_format_enum", {
+                                                                {0, "FP8_E5M2"},
+                                                                {1, "FP8_E4M3"},
+                                                            });
+  return {
+      {"LSCALE2", 32, 37},
+      {"NSCALE", 24, 31},
+      {"LSCALE", 16, 22},
+      {"OSC", 15},
+      {"OSM", 14},
+      {"F8D", 6, 8, &fp8_format_enum},
+      {"F8S2", 3, 5, &fp8_format_enum},
+      {"F8S1", 0, 2, &fp8_format_enum},
+  };
+}
+
 Arm64RegisterFlagsDetector::Fields
 Arm64RegisterFlagsDetector::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
   (void)hwcap;
diff --git a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
index a5bb38670b9cdf..0f3d53d93892bd 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterFlagsDetector_arm64.h
@@ -60,6 +60,7 @@ class Arm64RegisterFlagsDetector {
   static Fields DetectFPCRFields(uint64_t hwcap, uint64_t hwcap2);
   static Fields DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2);
   static Fields DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2);
+  static Fields DetectFPMRFields(uint64_t hwcap, uint64_t hwcap2);
 
   struct RegisterEntry {
     RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
@@ -69,12 +70,13 @@ class Arm64RegisterFlagsDetector {
     llvm::StringRef m_name;
     RegisterFlags m_flags;
     DetectorFn m_detector;
-  } m_registers[5] = {
+  } m_registers[6] = {
       RegisterEntry("cpsr", 4, DetectCPSRFields),
       RegisterEntry("fpsr", 4, DetectFPSRFields),
       RegisterEntry("fpcr", 4, DetectFPCRFields),
       RegisterEntry("mte_ctrl", 8, DetectMTECtrlFields),
       RegisterEntry("svcr", 8, DetectSVCRFields),
+      RegisterEntry("fpmr", 8, DetectFPMRFields),
   };
 
   // Becomes true once field detection has been run for all registers.
diff --git a/lldb/test/API/linux/aarch64/fpmr/TestAArch64LinuxFPMR.py b/lldb/test/API/linux/aarch64/fpmr/TestAArch64LinuxFPMR.py
index 5a3b8f501095e9..d022c8eb3d6cc4 100644
--- a/lldb/test/API/linux/aarch64/fpmr/TestAArch64LinuxFPMR.py
+++ b/lldb/test/API/linux/aarch64/fpmr/TestAArch64LinuxFPMR.py
@@ -45,6 +45,11 @@ def test_fpmr_register(self):
             substrs=["Floating Point Mode Register", f"fpmr = {expected_fpmr:#018x}"],
         )
 
+        if self.hasXMLSupport():
+            self.expect(
+                "register read fpmr", substrs=["LSCALE2 = 42", "F8S1 = FP8_E4M3 | 0x4"]
+            )
+
         # Write a value for the program to find. Same fields but with bit values
         # inverted.
         new_fpmr = (0b010101 << 32) | 0b010

@DavidSpickett
Copy link
Collaborator Author

Core files will be the next PR and a test will be added to ensure fields show up when using a core file too.

Copy link
Contributor

@omjavaid omjavaid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me but I have not tested this.

@DavidSpickett DavidSpickett merged commit 0e24611 into llvm:main Sep 26, 2024
9 checks passed
@DavidSpickett DavidSpickett deleted the fpmr-pr2 branch September 26, 2024 10:44
DavidSpickett added a commit that referenced this pull request Sep 26, 2024
#109934 added FPMR which
uses a bit in hwcaps greater than 31. So it marked the 1 with UL
which is fine on 64 bit systems but for 32 bit UL is 4 bytes.

Use ULL so we aren't invoking undefined behaviour.
Sterling-Augustine pushed a commit to Sterling-Augustine/llvm-project that referenced this pull request Sep 27, 2024
The FP8 formats have a "_" in the name so that they are:
1. Easier to read.
2. Possible to use in register expressions if/when they are supported.

Some other bits do have defined meanings but they are not simple to
name. Better that folks read the manual for those.

See this page for the full details:

https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers/FPMR--Floating-point-Mode-Register
Sterling-Augustine pushed a commit to Sterling-Augustine/llvm-project that referenced this pull request Sep 27, 2024
llvm#109934 added FPMR which
uses a bit in hwcaps greater than 31. So it marked the 1 with UL
which is fine on 64 bit systems but for 32 bit UL is 4 bytes.

Use ULL so we aren't invoking undefined behaviour.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants