xref: /llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestAArch64XMLRegistersSVEOnly.py (revision 497759e872a53964a54db941f3a1ed74446c5ed4)
1*497759e8SDavid Spickett""" Check that when a debug server provides XML that only defines SVE Z registers,
2*497759e8SDavid Spickett    and does not include Neon V registers, lldb creates sub-registers to represent
3*497759e8SDavid Spickett    the V registers as the bottom 128 bits of the Z registers.
4*497759e8SDavid Spickett
5*497759e8SDavid Spickett    qemu-aarch64 is one such debug server.
6*497759e8SDavid Spickett
7*497759e8SDavid Spickett    This also doubles as a test that lldb has a fallback path for registers of
8*497759e8SDavid Spickett    unknown type that are > 128 bits, as the SVE registers are here.
9*497759e8SDavid Spickett"""
10*497759e8SDavid Spickett
11*497759e8SDavid Spickettfrom textwrap import dedent
12*497759e8SDavid Spickettimport lldb
13*497759e8SDavid Spickettfrom lldbsuite.test.lldbtest import *
14*497759e8SDavid Spickettfrom lldbsuite.test.decorators import *
15*497759e8SDavid Spickettfrom lldbsuite.test.gdbclientutils import *
16*497759e8SDavid Spickettfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
17*497759e8SDavid Spickett
18*497759e8SDavid Spickett
19*497759e8SDavid Spickettclass Responder(MockGDBServerResponder):
20*497759e8SDavid Spickett    def __init__(self):
21*497759e8SDavid Spickett        super().__init__()
22*497759e8SDavid Spickett        self.vg = 4
23*497759e8SDavid Spickett        self.pc = 0xA0A0A0A0A0A0A0A0
24*497759e8SDavid Spickett
25*497759e8SDavid Spickett    def qXferRead(self, obj, annex, offset, length):
26*497759e8SDavid Spickett        if annex == "target.xml":
27*497759e8SDavid Spickett            # Note that QEMU sends the current SVE size in XML and the debugger
28*497759e8SDavid Spickett            # then reads vg to know the latest size.
29*497759e8SDavid Spickett            return (
30*497759e8SDavid Spickett                dedent(
31*497759e8SDavid Spickett                    """\
32*497759e8SDavid Spickett              <?xml version="1.0"?>
33*497759e8SDavid Spickett              <target version="1.0">
34*497759e8SDavid Spickett                <architecture>aarch64</architecture>
35*497759e8SDavid Spickett                <feature name="org.gnu.gdb.aarch64.core">
36*497759e8SDavid Spickett                  <reg name="pc" regnum="0" bitsize="64"/>
37*497759e8SDavid Spickett                  <reg name="vg" regnum="1" bitsize="64"/>
38*497759e8SDavid Spickett                  <reg name="z0" regnum="2" bitsize="2048" type="not_a_type"/>
39*497759e8SDavid Spickett                </feature>
40*497759e8SDavid Spickett              </target>"""
41*497759e8SDavid Spickett                ),
42*497759e8SDavid Spickett                False,
43*497759e8SDavid Spickett            )
44*497759e8SDavid Spickett
45*497759e8SDavid Spickett        return (None,)
46*497759e8SDavid Spickett
47*497759e8SDavid Spickett    def readRegister(self, regnum):
48*497759e8SDavid Spickett        return "E01"
49*497759e8SDavid Spickett
50*497759e8SDavid Spickett    def readRegisters(self):
51*497759e8SDavid Spickett        return "".join(
52*497759e8SDavid Spickett            [
53*497759e8SDavid Spickett                # 64 bit PC.
54*497759e8SDavid Spickett                f"{self.pc:x}",
55*497759e8SDavid Spickett                # 64 bit vg
56*497759e8SDavid Spickett                f"0{self.vg}00000000000000",
57*497759e8SDavid Spickett                # Enough data for 256 and 512 bit SVE.
58*497759e8SDavid Spickett                "".join([f"{n:02x}" * 4 for n in range(1, 17)]),
59*497759e8SDavid Spickett            ]
60*497759e8SDavid Spickett        )
61*497759e8SDavid Spickett
62*497759e8SDavid Spickett    def cont(self):
63*497759e8SDavid Spickett        # vg is expedited so that lldb can resize the SVE registers.
64*497759e8SDavid Spickett        return f"T02thread:1ff0d;threads:1ff0d;thread-pcs:{self.pc};01:0{self.vg}00000000000000;"
65*497759e8SDavid Spickett
66*497759e8SDavid Spickett    def writeRegisters(self, registers_hex):
67*497759e8SDavid Spickett        # We get a block of data containing values in regnum order.
68*497759e8SDavid Spickett        self.vg = int(registers_hex[16:18])
69*497759e8SDavid Spickett        return "OK"
70*497759e8SDavid Spickett
71*497759e8SDavid Spickett
72*497759e8SDavid Spickettclass TestXMLRegisterFlags(GDBRemoteTestBase):
73*497759e8SDavid Spickett    def check_regs(self, vg):
74*497759e8SDavid Spickett        # Each 32 bit chunk repeats n.
75*497759e8SDavid Spickett        z0_value = " ".join(
76*497759e8SDavid Spickett            [" ".join([f"0x{n:02x}"] * 4) for n in range(1, (vg * 2) + 1)]
77*497759e8SDavid Spickett        )
78*497759e8SDavid Spickett
79*497759e8SDavid Spickett        self.expect(
80*497759e8SDavid Spickett            "register read vg z0 v0 s0 d0",
81*497759e8SDavid Spickett            substrs=[
82*497759e8SDavid Spickett                f"      vg = 0x000000000000000{vg}\n"
83*497759e8SDavid Spickett                "      z0 = {" + z0_value + "}\n"
84*497759e8SDavid Spickett                "      v0 = {0x01 0x01 0x01 0x01 0x02 0x02 0x02 0x02 0x03 0x03 0x03 0x03 0x04 0x04 0x04 0x04}\n"
85*497759e8SDavid Spickett                "      s0 = 2.36942783E-38\n"
86*497759e8SDavid Spickett                "      d0 = 5.3779407333977203E-299\n"
87*497759e8SDavid Spickett            ],
88*497759e8SDavid Spickett        )
89*497759e8SDavid Spickett
90*497759e8SDavid Spickett        self.expect("register read s0 --format uint32", substrs=["s0 = {0x01010101}"])
91*497759e8SDavid Spickett        self.expect(
92*497759e8SDavid Spickett            "register read d0 --format uint64",
93*497759e8SDavid Spickett            substrs=["d0 = {0x0202020201010101}"],
94*497759e8SDavid Spickett        )
95*497759e8SDavid Spickett
96*497759e8SDavid Spickett    @skipIfXmlSupportMissing
97*497759e8SDavid Spickett    @skipIfRemote
98*497759e8SDavid Spickett    @skipIfLLVMTargetMissing("AArch64")
99*497759e8SDavid Spickett    def test_v_sub_registers(self):
100*497759e8SDavid Spickett        self.server.responder = Responder()
101*497759e8SDavid Spickett        target = self.dbg.CreateTarget("")
102*497759e8SDavid Spickett
103*497759e8SDavid Spickett        if self.TraceOn():
104*497759e8SDavid Spickett            self.runCmd("log enable gdb-remote packets")
105*497759e8SDavid Spickett            self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets"))
106*497759e8SDavid Spickett
107*497759e8SDavid Spickett        process = self.connect(target)
108*497759e8SDavid Spickett        lldbutil.expect_state_changes(
109*497759e8SDavid Spickett            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
110*497759e8SDavid Spickett        )
111*497759e8SDavid Spickett
112*497759e8SDavid Spickett        self.check_regs(4)
113*497759e8SDavid Spickett
114*497759e8SDavid Spickett        # Now increase the SVE length and continue. The mock will respond with a new
115*497759e8SDavid Spickett        # vg and lldb will reconfigure the register defs. This should not break the
116*497759e8SDavid Spickett        # sub-registers.
117*497759e8SDavid Spickett
118*497759e8SDavid Spickett        self.runCmd("register write vg 8")
119*497759e8SDavid Spickett        self.expect("continue", substrs=["stop reason = signal SIGINT"])
120*497759e8SDavid Spickett
121*497759e8SDavid Spickett        self.check_regs(8)
122