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