mgorny updated this revision to Diff 379771.
mgorny marked an inline comment as done.
mgorny added a comment.

Use inline lists instead of `for` loops for registers. Use `llvm::SmallDense*` 
types with `StringRef`s.


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

https://reviews.llvm.org/D108831

Files:
  lldb/source/Plugins/ABI/X86/ABIX86.cpp
  lldb/source/Plugins/ABI/X86/ABIX86.h
  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
@@ -163,6 +163,67 @@
                    ["xmm1 = {0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 "
                     "0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0}"])
 
+        # test pseudo-registers
+        self.match("register read ecx",
+                   ["ecx = 0x04030201"])
+        self.match("register read cx",
+                   ["cx = 0x0201"])
+        self.match("register read ch",
+                   ["ch = 0x02"])
+        self.match("register read cl",
+                   ["cl = 0x01"])
+        self.match("register read r8d",
+                   ["r8d = 0x64636261"])
+        self.match("register read r8w",
+                   ["r8w = 0x6261"])
+        self.match("register read r8l",
+                   ["r8l = 0x61"])
+        self.match("register read mm0",
+                   ["mm0 = 0x0807060504030201"])
+        self.match("register read mm1",
+                   ["mm1 = 0x1817161514131211"])
+
+        # test writing into pseudo-registers
+        self.runCmd("register write ecx 0xfffefdfc")
+        reg_data[0] = "fcfdfeff05060708"
+        self.assertPacketLogContains(["G" + "".join(reg_data)])
+        self.match("register read rcx",
+                   ["rcx = 0x08070605fffefdfc"])
+
+        self.runCmd("register write cx 0xfbfa")
+        reg_data[0] = "fafbfeff05060708"
+        self.assertPacketLogContains(["G" + "".join(reg_data)])
+        self.match("register read ecx",
+                   ["ecx = 0xfffefbfa"])
+        self.match("register read rcx",
+                   ["rcx = 0x08070605fffefbfa"])
+
+        self.runCmd("register write ch 0xf9")
+        reg_data[0] = "faf9feff05060708"
+        self.assertPacketLogContains(["G" + "".join(reg_data)])
+        self.match("register read cx",
+                   ["cx = 0xf9fa"])
+        self.match("register read ecx",
+                   ["ecx = 0xfffef9fa"])
+        self.match("register read rcx",
+                   ["rcx = 0x08070605fffef9fa"])
+
+        self.runCmd("register write cl 0xf8")
+        reg_data[0] = "f8f9feff05060708"
+        self.assertPacketLogContains(["G" + "".join(reg_data)])
+        self.match("register read cx",
+                   ["cx = 0xf9f8"])
+        self.match("register read ecx",
+                   ["ecx = 0xfffef9f8"])
+        self.match("register read rcx",
+                   ["rcx = 0x08070605fffef9f8"])
+
+        self.runCmd("register write mm0 0xfffefdfcfbfaf9f8")
+        reg_data[10] = "f8f9fafbfcfdfeff090a"
+        self.assertPacketLogContains(["G" + "".join(reg_data)])
+        self.match("register read st0",
+                   ["st0 = {0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff 0x09 0x0a}"])
+
     @skipIfXmlSupportMissing
     @skipIfRemote
     @skipIfLLVMTargetMissing("X86")
@@ -272,11 +333,25 @@
         # test generic aliases
         self.match("register read fp",
                    ["ebp = 0x54535251"])
+        self.match("register read sp",
+                   ["esp = 0x44434241"])
         self.match("register read pc",
                    ["eip = 0x84838281"])
         self.match("register read flags",
                    ["eflags = 0x94939291"])
 
+        # test pseudo-registers
+        self.match("register read cx",
+                   ["cx = 0x1211"])
+        self.match("register read ch",
+                   ["ch = 0x12"])
+        self.match("register read cl",
+                   ["cl = 0x11"])
+        self.match("register read mm0",
+                   ["mm0 = 0x0807060504030201"])
+        self.match("register read mm1",
+                   ["mm1 = 0x1817161514131211"])
+
         # both stX and xmmX should be displayed as vectors
         self.match("register read st0",
                    ["st0 = {0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a}"])
@@ -289,6 +364,35 @@
                    ["xmm1 = {0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 "
                     "0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0}"])
 
+        # test writing into pseudo-registers
+        self.runCmd("register write cx 0xfbfa")
+        reg_data[1] = "fafb1314"
+        self.assertPacketLogContains(["G" + "".join(reg_data)])
+        self.match("register read ecx",
+                   ["ecx = 0x1413fbfa"])
+
+        self.runCmd("register write ch 0xf9")
+        reg_data[1] = "faf91314"
+        self.assertPacketLogContains(["G" + "".join(reg_data)])
+        self.match("register read cx",
+                   ["cx = 0xf9fa"])
+        self.match("register read ecx",
+                   ["ecx = 0x1413f9fa"])
+
+        self.runCmd("register write cl 0xf8")
+        reg_data[1] = "f8f91314"
+        self.assertPacketLogContains(["G" + "".join(reg_data)])
+        self.match("register read cx",
+                   ["cx = 0xf9f8"])
+        self.match("register read ecx",
+                   ["ecx = 0x1413f9f8"])
+
+        self.runCmd("register write mm0 0xfffefdfcfbfaf9f8")
+        reg_data[10] = "f8f9fafbfcfdfeff090a"
+        self.assertPacketLogContains(["G" + "".join(reg_data)])
+        self.match("register read st0",
+                   ["st0 = {0xf8 0xf9 0xfa 0xfb 0xfc 0xfd 0xfe 0xff 0x09 0x0a}"])
+
     @skipIfXmlSupportMissing
     @skipIfRemote
     @skipIfLLVMTargetMissing("AArch64")
Index: lldb/source/Plugins/ABI/X86/ABIX86.h
===================================================================
--- lldb/source/Plugins/ABI/X86/ABIX86.h
+++ lldb/source/Plugins/ABI/X86/ABIX86.h
@@ -17,6 +17,10 @@
   static void Initialize();
   static void Terminate();
 
+protected:
+  void AugmentRegisterInfo(
+      std::vector<lldb_private::DynamicRegisterInfo::Register> &regs) override;
+
 private:
   using lldb_private::MCBasedABI::MCBasedABI;
 };
Index: lldb/source/Plugins/ABI/X86/ABIX86.cpp
===================================================================
--- lldb/source/Plugins/ABI/X86/ABIX86.cpp
+++ lldb/source/Plugins/ABI/X86/ABIX86.cpp
@@ -6,12 +6,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "ABIX86.h"
 #include "ABIMacOSX_i386.h"
 #include "ABISysV_i386.h"
 #include "ABISysV_x86_64.h"
 #include "ABIWindows_x86_64.h"
+#include "ABIX86.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
 
 LLDB_PLUGIN_DEFINE(ABIX86)
 
@@ -28,3 +32,141 @@
   ABISysV_x86_64::Terminate();
   ABIWindows_x86_64::Terminate();
 }
+
+enum class RegKind {
+  GPR32 = 0,
+  GPR16,
+  GPR8h,
+  GPR8,
+
+  MM = 0,
+};
+
+typedef llvm::SmallDenseMap<llvm::StringRef, llvm::SmallVector<llvm::StringRef, 4>, 16>
+    RegisterMap;
+
+static void addPartialRegisters(
+    std::vector<DynamicRegisterInfo::Register> &regs,
+    llvm::ArrayRef<uint32_t> base_reg_indices, RegisterMap reg_names,
+    uint32_t base_size, RegKind name_index, lldb::Encoding encoding,
+    lldb::Format format, uint32_t subreg_size, uint32_t subreg_offset = 0) {
+  for (uint32_t base_index : base_reg_indices) {
+    if (base_index == LLDB_INVALID_REGNUM)
+      break;
+    assert(base_index < regs.size());
+    DynamicRegisterInfo::Register &full_reg = regs[base_index];
+    const llvm::StringRef &subreg_name =
+        reg_names[full_reg.name.AsCString()][static_cast<int>(name_index)];
+    if (subreg_name.empty() || full_reg.byte_size != base_size)
+      continue;
+
+    lldb_private::DynamicRegisterInfo::Register subreg{
+        lldb_private::ConstString(subreg_name),
+        lldb_private::ConstString(),
+        lldb_private::ConstString("supplementary registers"),
+        subreg_size,
+        LLDB_INVALID_INDEX32,
+        encoding,
+        format,
+        LLDB_INVALID_REGNUM,
+        LLDB_INVALID_REGNUM,
+        LLDB_INVALID_REGNUM,
+        LLDB_INVALID_REGNUM,
+        {base_index},
+        {},
+        subreg_offset};
+
+    addSupplementaryRegister(regs, subreg);
+  }
+}
+
+void ABIX86::AugmentRegisterInfo(
+    std::vector<DynamicRegisterInfo::Register> &regs) {
+  MCBasedABI::AugmentRegisterInfo(regs);
+
+  ProcessSP process_sp = GetProcessSP();
+  if (!process_sp)
+    return;
+
+  bool is64bit =
+      process_sp->GetTarget().GetArchitecture().GetAddressByteSize() == 8;
+  uint32_t gpr_base_size = is64bit ? 8 : 4;
+
+  typedef RegisterMap::value_type RegPair;
+#define GPR_BASE(basename) (is64bit ? "r" basename : "e" basename)
+  RegisterMap gpr_regs{{
+      RegPair(GPR_BASE("ax"), {"eax", "ax", "ah", "al"}),
+      RegPair(GPR_BASE("bx"), {"ebx", "bx", "bh", "bl"}),
+      RegPair(GPR_BASE("cx"), {"ecx", "cx", "ch", "cl"}),
+      RegPair(GPR_BASE("dx"), {"edx", "dx", "dh", "dl"}),
+      RegPair(GPR_BASE("si"), {"esi", "si", "", "sil"}),
+      RegPair(GPR_BASE("di"), {"edi", "di", "", "dil"}),
+      RegPair(GPR_BASE("bp"), {"ebp", "bp", "", "bpl"}),
+      RegPair(GPR_BASE("sp"), {"esp", "sp", "", "spl"}),
+  }};
+#undef GPR_BASE
+  if (is64bit) {
+#define R(base) RegPair(base, {base "d", base "w", "", base "l"})
+    RegisterMap amd64_regs{{
+        R("r8"),
+        R("r9"),
+        R("r10"),
+        R("r11"),
+        R("r12"),
+        R("r13"),
+        R("r14"),
+        R("r15"),
+    }};
+#undef R
+    gpr_regs.insert(amd64_regs.begin(), amd64_regs.end());
+  }
+
+  RegisterMap st_regs{{
+      RegPair("st0", {"mm0"}),
+      RegPair("st1", {"mm1"}),
+      RegPair("st2", {"mm2"}),
+      RegPair("st3", {"mm3"}),
+      RegPair("st4", {"mm4"}),
+      RegPair("st5", {"mm5"}),
+      RegPair("st6", {"mm6"}),
+      RegPair("st7", {"mm7"}),
+  }};
+
+  // regs from gpr_basenames, in list order
+  std::vector<uint32_t> gpr_base_reg_indices;
+  // st0..st7, in list order
+  std::vector<uint32_t> st_reg_indices;
+  // map used for fast register lookups
+  llvm::SmallDenseSet<llvm::StringRef, 64> subreg_name_set;
+
+  // put all subreg names into the lookup set
+  for (const RegisterMap &regset : {gpr_regs, st_regs}) {
+    for (const RegPair &kv : regset)
+      subreg_name_set.insert(kv.second.begin(), kv.second.end());
+  }
+
+  for (const auto &x : llvm::enumerate(regs)) {
+    const char *reg_name = x.value().name.AsCString();
+    // find expected base registers
+    if (gpr_regs.find(reg_name) != gpr_regs.end())
+      gpr_base_reg_indices.push_back(x.index());
+    else if (st_regs.find(reg_name) != st_regs.end())
+      st_reg_indices.push_back(x.index());
+    // abort if at least one sub-register is already present
+    else if (llvm::is_contained(subreg_name_set, reg_name))
+      return;
+  }
+
+  if (is64bit)
+    addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
+                        RegKind::GPR32, eEncodingUint, eFormatHex, 4);
+  addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
+                      RegKind::GPR16, eEncodingUint, eFormatHex, 2);
+  addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
+                      RegKind::GPR8h, eEncodingUint, eFormatHex, 1, 1);
+  addPartialRegisters(regs, gpr_base_reg_indices, gpr_regs, gpr_base_size,
+                      RegKind::GPR8, eEncodingUint, eFormatHex, 1);
+
+  addPartialRegisters(regs, st_reg_indices, st_regs, 10, RegKind::MM,
+                      eEncodingUint, eFormatHex, 8);
+}
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to