mgorny updated this revision to Diff 377835.
mgorny added a comment.

Rebase.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109876/new/

https://reviews.llvm.org/D109876

Files:
  lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
  lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py

Index: lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
===================================================================
--- lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
+++ lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py
@@ -380,6 +380,7 @@
                 return "".join(reg_data)
 
             def writeRegisters(self, reg_hex):
+                reg_data[:] = [reg_hex]
                 return "OK"
 
             def haltReason(self):
@@ -429,3 +430,43 @@
                    ["v0 = {0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90}"])
         self.match("register read v31",
                    ["v31 = {0xa1 0xa2 0xa3 0xa4 0xa5 0xa6 0xa7 0xa8 0xa9 0xaa 0xab 0xac 0xad 0xae 0xaf 0xb0}"])
+
+        # test partial registers
+        self.match("register read w0",
+                   ["w0 = 0x04030201"])
+        self.runCmd("register write w0 0xfffefdfc")
+        self.match("register read x0",
+                   ["x0 = 0x08070605fffefdfc"])
+
+        self.match("register read w1",
+                   ["w1 = 0x14131211"])
+        self.runCmd("register write w1 0xefeeedec")
+        self.match("register read x1",
+                   ["x1 = 0x18171615efeeedec"])
+
+        self.match("register read w30",
+                   ["w30 = 0x44434241"])
+        self.runCmd("register write w30 0xdfdedddc")
+        self.match("register read x30",
+                   ["x30 = 0x48474645dfdedddc"])
+
+        self.match("register read w31",
+                   ["w31 = 0x54535251"])
+        self.runCmd("register write w31 0xcfcecdcc")
+        self.match("register read x31",
+                   ["sp = 0x58575655cfcecdcc"])
+
+        # test FPU registers (overlapping with vector registers)
+        self.runCmd("register write d0 16")
+        self.match("register read v0",
+                   ["v0 = {0x00 0x00 0x00 0x00 0x00 0x00 0x30 0x40 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90}"])
+        self.runCmd("register write v31 '{0x00 0x00 0x00 0x00 0x00 0x00 0x50 0x40 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff}'")
+        self.match("register read d31",
+                   ["d31 = 64"])
+
+        self.runCmd("register write s0 32")
+        self.match("register read v0",
+                   ["v0 = {0x00 0x00 0x00 0x42 0x00 0x00 0x30 0x40 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90}"])
+        self.runCmd("register write v31 '{0x00 0x00 0x00 0x43 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff}'")
+        self.match("register read s31",
+                   ["s31 = 128"])
Index: lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
===================================================================
--- lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
+++ lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp
@@ -71,14 +71,93 @@
       .Default(LLDB_INVALID_REGNUM);
 }
 
+static void addPartialRegister(
+    std::vector<lldb_private::DynamicRegisterInfo::Register> &regs,
+    uint32_t full_reg_index, uint32_t full_reg_size,
+    const std::string &partial_reg_name, uint32_t partial_reg_size,
+    lldb::Encoding encoding, lldb::Format format, uint32_t &next_regnum_lldb) {
+  if (full_reg_index == LLDB_INVALID_REGNUM ||
+      regs[full_reg_index].byte_size != full_reg_size)
+    return;
+
+  lldb_private::DynamicRegisterInfo::Register partial_reg{
+      lldb_private::ConstString(partial_reg_name),
+      lldb_private::ConstString(),
+      lldb_private::ConstString("partial registers"),
+      partial_reg_size,
+      LLDB_INVALID_INDEX32,
+      encoding,
+      format,
+      LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM,
+      LLDB_INVALID_REGNUM,
+      {full_reg_index},
+      {}};
+
+  addSupplementaryRegister(regs, partial_reg);
+}
+
 void ABIAArch64::AugmentRegisterInfo(
     std::vector<lldb_private::DynamicRegisterInfo::Register> &regs) {
   lldb_private::MCBasedABI::AugmentRegisterInfo(regs);
 
   lldb_private::ConstString sp_string{"sp"};
-  for (lldb_private::DynamicRegisterInfo::Register &info : regs) {
+
+  std::array<uint32_t, 32> x_regs{LLDB_INVALID_REGNUM};
+  std::array<uint32_t, 32> v_regs{LLDB_INVALID_REGNUM};
+  std::array<bool, 32> have_w_regs{false};
+  std::array<bool, 32> have_s_regs{false};
+  std::array<bool, 32> have_d_regs{false};
+
+  for (auto it : llvm::enumerate(regs)) {
+    lldb_private::DynamicRegisterInfo::Register &info = it.value();
     // GDB sends x31 as "sp".  Add the "x31" alt_name for convenience.
     if (info.name == sp_string && !info.alt_name)
       info.alt_name.SetCString("x31");
+
+    unsigned int reg_num;
+    auto get_reg = [&info, &reg_num](const char *prefix) {
+      llvm::StringRef reg_name = info.name.GetStringRef();
+      llvm::StringRef alt_name = info.alt_name.GetStringRef();
+      return (reg_name.consume_front(prefix) &&
+              llvm::to_integer(reg_name, reg_num, 10) && reg_num < 32) ||
+             (alt_name.consume_front(prefix) &&
+              llvm::to_integer(alt_name, reg_num, 10) && reg_num < 32);
+    };
+
+    if (get_reg("x"))
+      x_regs[reg_num] = it.index();
+    if (get_reg("v"))
+      v_regs[reg_num] = it.index();
+    if (get_reg("w"))
+      have_w_regs[reg_num] = true;
+    if (get_reg("s"))
+      have_s_regs[reg_num] = true;
+    if (get_reg("d"))
+      have_d_regs[reg_num] = true;
+  }
+
+  uint32_t next_regnum_lldb = regs.size();
+  // Create aliases for partial registers: wN for xN, and sN/dN for vN.
+  for (int i = 0; i < 32; i++) {
+    if (!have_w_regs[i])
+      addPartialRegister(regs, x_regs[i], 8, llvm::formatv("w{0}", i), 4,
+                         lldb::eEncodingUint, lldb::eFormatHex,
+                         next_regnum_lldb);
+  }
+
+  for (int i = 0; i < 32; i++) {
+    if (!have_s_regs[i])
+      addPartialRegister(regs, v_regs[i], 16, llvm::formatv("s{0}", i), 4,
+                         lldb::eEncodingIEEE754, lldb::eFormatFloat,
+                         next_regnum_lldb);
+  }
+
+  for (int i = 0; i < 32; i++) {
+    if (!have_d_regs[i])
+      addPartialRegister(regs, v_regs[i], 16, llvm::formatv("d{0}", i), 8,
+                         lldb::eEncodingIEEE754, lldb::eFormatFloat,
+                         next_regnum_lldb);
   }
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to