[lldb][AArch64][Linux] Add register field information for SME's SVCR register (#71809)

This register is a pseudo register but mirrors the architectural
register's contents. See:
https://developer.arm.com/documentation/ddi0616/latest/

For the full details. Example output:
```
(lldb) register read svcr
    svcr = 0x0000000000000002
         = (ZA = 1, SM = 0)
```
This commit is contained in:
David Spickett 2023-11-10 09:30:11 +00:00 committed by GitHub
parent 5b0f703918
commit 9ad25f2352
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 9 deletions

View File

@ -24,6 +24,19 @@
using namespace lldb_private;
LinuxArm64RegisterFlags::Fields
LinuxArm64RegisterFlags::DetectSVCRFields(uint64_t hwcap, uint64_t hwcap2) {
(void)hwcap;
(void)hwcap2;
// Represents the pseudo register that lldb-server builds, which itself
// matches the architectural register SCVR. The fields match SVCR in the Arm
// manual.
return {
{"ZA", 1},
{"SM", 0},
};
}
LinuxArm64RegisterFlags::Fields
LinuxArm64RegisterFlags::DetectMTECtrlFields(uint64_t hwcap, uint64_t hwcap2) {
(void)hwcap;

View File

@ -59,6 +59,7 @@ private:
static Fields DetectFPSRFields(uint64_t hwcap, uint64_t hwcap2);
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);
struct RegisterEntry {
RegisterEntry(llvm::StringRef name, unsigned size, DetectorFn detector)
@ -68,11 +69,12 @@ private:
llvm::StringRef m_name;
RegisterFlags m_flags;
DetectorFn m_detector;
} m_registers[4] = {
} m_registers[5] = {
RegisterEntry("cpsr", 4, DetectCPSRFields),
RegisterEntry("fpsr", 4, DetectFPSRFields),
RegisterEntry("fpcr", 4, DetectFPCRFields),
RegisterEntry("mte_ctrl", 8, DetectMTECtrlFields),
RegisterEntry("svcr", 8, DetectSVCRFields),
};
// Becomes true once field detection has been run for all registers.

View File

@ -180,9 +180,12 @@ class AArch64ZATestCase(TestBase):
self.runCmd("register read " + sve_reg_names)
sve_values = self.res.GetOutput()
svcr_value = 1 if sve_mode == Mode.SSVE else 0
if za_state == ZA.Enabled:
svcr_value += 2
za = 1 if za_state == ZA.Enabled else 0
sm = 1 if sve_mode == Mode.SSVE else 0
svcr_value = "0x{:016x}".format((za << 1) | sm)
expected_svcr = [svcr_value]
if self.hasXMLSupport():
expected_svcr.append("(ZA = {}, SM = {})".format(za, sm))
has_zt0 = self.isAArch64SME2()
@ -201,7 +204,8 @@ class AArch64ZATestCase(TestBase):
self.assertEqual(start_vg, self.read_vg())
self.expect("register read " + sve_reg_names, substrs=[sve_values])
self.expect("register read svcr", substrs=["0x{:016x}".format(svcr_value)])
self.expect("register read svcr", substrs=expected_svcr)
for expr in exprs:
expr_cmd = "expression {}()".format(expr)

View File

@ -5,17 +5,17 @@ Check that LLDB can read Scalable Matrix Extension (SME) data from core files.
import lldb
import itertools
from enum import Enum
from enum import IntEnum
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
class Mode(Enum):
class Mode(IntEnum):
SVE = 0
SSVE = 1
class ZA(Enum):
class ZA(IntEnum):
Disabled = 0
Enabled = 1
@ -56,7 +56,12 @@ class AArch64LinuxSMECoreFileTestCase(TestBase):
svcr = 1 if sve_mode == Mode.SSVE else 0
if za == ZA.Enabled:
svcr |= 2
self.expect("register read svcr", substrs=["0x{:016x}".format(svcr)])
expected_svcr = ["0x{:016x}".format(svcr)]
if self.hasXMLSupport():
expected_svcr.append("(ZA = {:d}, SM = {})".format(za, sve_mode))
self.expect("register read svcr", substrs=expected_svcr)
repeat_bytes = lambda v, n: " ".join(["0x{:02x}".format(v)] * n)