[Lldb-commits] [lldb] 24332f0 - [lldb] [Process/FreeBSD] Introduce mips64 FPU reg support

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Fri Sep 10 00:14:00 PDT 2021


Author: Michał Górny
Date: 2021-09-10T09:13:15+02:00
New Revision: 24332f0e27e17bbe3edfe3d66636c48c17d6ad5f

URL: https://github.com/llvm/llvm-project/commit/24332f0e27e17bbe3edfe3d66636c48c17d6ad5f
DIFF: https://github.com/llvm/llvm-project/commit/24332f0e27e17bbe3edfe3d66636c48c17d6ad5f.diff

LOG: [lldb] [Process/FreeBSD] Introduce mips64 FPU reg support

Differential Revision: https://reviews.llvm.org/D96766

Added: 
    

Modified: 
    lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
    lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
    lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
    lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h
    lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
    lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
index 8e722c09314c..d93b7fd33815 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
@@ -15,6 +15,7 @@
 #include "lldb/Utility/Status.h"
 
 #include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+#include "Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h"
 
 // clang-format off
 #include <sys/param.h>
@@ -59,11 +60,32 @@ uint32_t NativeRegisterContextFreeBSD_mips64::GetUserRegisterCount() const {
   return count;
 }
 
+llvm::Optional<NativeRegisterContextFreeBSD_mips64::RegSetKind>
+NativeRegisterContextFreeBSD_mips64::GetSetForNativeRegNum(
+    uint32_t reg_num) const {
+  switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+  case llvm::Triple::mips64:
+    if (reg_num >= k_first_gpr_mips64 && reg_num <= k_last_gpr_mips64)
+      return GPRegSet;
+    if (reg_num >= k_first_fpr_mips64 && reg_num <= k_last_fpr_mips64)
+      return FPRegSet;
+    break;
+  default:
+    llvm_unreachable("Unhandled target architecture.");
+  }
+
+  llvm_unreachable("Register does not belong to any register set");
+}
+
 Status NativeRegisterContextFreeBSD_mips64::ReadRegisterSet(RegSetKind set) {
   switch (set) {
   case GPRegSet:
     return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
                                                m_reg_data.data());
+  case FPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(
+        PT_GETFPREGS, m_thread.GetID(),
+        m_reg_data.data() + GetRegisterInfo().GetGPRSize());
   }
   llvm_unreachable("NativeRegisterContextFreeBSD_mips64::ReadRegisterSet");
 }
@@ -73,6 +95,10 @@ Status NativeRegisterContextFreeBSD_mips64::WriteRegisterSet(RegSetKind set) {
   case GPRegSet:
     return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
                                                m_reg_data.data());
+  case FPRegSet:
+    return NativeProcessFreeBSD::PtraceWrapper(
+        PT_SETFPREGS, m_thread.GetID(),
+        m_reg_data.data() + GetRegisterInfo().GetGPRSize());
   }
   llvm_unreachable("NativeRegisterContextFreeBSD_mips64::WriteRegisterSet");
 }
@@ -94,7 +120,16 @@ NativeRegisterContextFreeBSD_mips64::ReadRegister(const RegisterInfo *reg_info,
                                                ? reg_info->name
                                                : "<unknown register>");
 
-  RegSetKind set = GPRegSet;
+  llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+  if (!opt_set) {
+    // This is likely an internal register for lldb use only and should not be
+    // directly queried.
+    error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+                                   reg_info->name);
+    return error;
+  }
+
+  RegSetKind set = opt_set.getValue();
   error = ReadRegisterSet(set);
   if (error.Fail())
     return error;
@@ -119,7 +154,16 @@ Status NativeRegisterContextFreeBSD_mips64::WriteRegister(
                                                ? reg_info->name
                                                : "<unknown register>");
 
-  RegSetKind set = GPRegSet;
+  llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+  if (!opt_set) {
+    // This is likely an internal register for lldb use only and should not be
+    // directly queried.
+    error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+                                   reg_info->name);
+    return error;
+  }
+
+  RegSetKind set = opt_set.getValue();
   error = ReadRegisterSet(set);
   if (error.Fail())
     return error;
@@ -139,6 +183,10 @@ Status NativeRegisterContextFreeBSD_mips64::ReadAllRegisterValues(
   if (error.Fail())
     return error;
 
+  error = ReadRegisterSet(FPRegSet);
+  if (error.Fail())
+    return error;
+
   data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
   uint8_t *dst = data_sp->GetBytes();
   ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
@@ -175,7 +223,11 @@ Status NativeRegisterContextFreeBSD_mips64::WriteAllRegisterValues(
   }
   ::memcpy(m_reg_data.data(), src, m_reg_data.size());
 
-  return WriteRegisterSet(GPRegSet);
+  error = WriteRegisterSet(GPRegSet);
+  if (error.Fail())
+    return error;
+
+  return WriteRegisterSet(FPRegSet);
 }
 
 llvm::Error NativeRegisterContextFreeBSD_mips64::CopyHardwareWatchpointsFrom(

diff  --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
index 6a3eb86a9231..8e300ed829c9 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
@@ -54,8 +54,11 @@ class NativeRegisterContextFreeBSD_mips64
 private:
   enum RegSetKind {
     GPRegSet,
+    FPRegSet,
   };
-  std::array<uint8_t, sizeof(reg)> m_reg_data;
+  std::array<uint8_t, sizeof(reg) + sizeof(fpreg)> m_reg_data;
+
+  llvm::Optional<RegSetKind> GetSetForNativeRegNum(uint32_t reg_num) const;
 
   Status ReadRegisterSet(RegSetKind set);
   Status WriteRegisterSet(RegSetKind set);

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
index 0c5d34f345db..7b4c7be21f74 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp
@@ -14,27 +14,53 @@
 using namespace lldb_private;
 using namespace lldb;
 
-static const uint32_t g_gpr_regnums[] = {
-    gpr_zero_mips64,  gpr_r1_mips64,    gpr_r2_mips64,    gpr_r3_mips64,
-    gpr_r4_mips64,    gpr_r5_mips64,    gpr_r6_mips64,    gpr_r7_mips64,
-    gpr_r8_mips64,    gpr_r9_mips64,    gpr_r10_mips64,   gpr_r11_mips64,
-    gpr_r12_mips64,   gpr_r13_mips64,   gpr_r14_mips64,   gpr_r15_mips64,
-    gpr_r16_mips64,   gpr_r17_mips64,   gpr_r18_mips64,   gpr_r19_mips64,
-    gpr_r20_mips64,   gpr_r21_mips64,   gpr_r22_mips64,   gpr_r23_mips64,
-    gpr_r24_mips64,   gpr_r25_mips64,   gpr_r26_mips64,   gpr_r27_mips64,
-    gpr_gp_mips64,    gpr_sp_mips64,    gpr_r30_mips64,   gpr_ra_mips64,
-    gpr_sr_mips64,    gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
-    gpr_cause_mips64, gpr_pc_mips64,    gpr_ic_mips64,    gpr_dummy_mips64};
+static const uint32_t g_gp_regnums_mips64[] = {
+    gpr_zero_mips64,    gpr_r1_mips64,    gpr_r2_mips64,    gpr_r3_mips64,
+    gpr_r4_mips64,      gpr_r5_mips64,    gpr_r6_mips64,    gpr_r7_mips64,
+    gpr_r8_mips64,      gpr_r9_mips64,    gpr_r10_mips64,   gpr_r11_mips64,
+    gpr_r12_mips64,     gpr_r13_mips64,   gpr_r14_mips64,   gpr_r15_mips64,
+    gpr_r16_mips64,     gpr_r17_mips64,   gpr_r18_mips64,   gpr_r19_mips64,
+    gpr_r20_mips64,     gpr_r21_mips64,   gpr_r22_mips64,   gpr_r23_mips64,
+    gpr_r24_mips64,     gpr_r25_mips64,   gpr_r26_mips64,   gpr_r27_mips64,
+    gpr_gp_mips64,      gpr_sp_mips64,    gpr_r30_mips64,   gpr_ra_mips64,
+    gpr_sr_mips64,      gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
+    gpr_cause_mips64,   gpr_pc_mips64,    gpr_ic_mips64,    gpr_dummy_mips64,
+    LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) -
+                      1 ==
+                  k_num_gpr_registers_mips64,
+              "g_gp_regnums_mips64 has wrong number of register infos");
+
+const uint32_t g_fp_regnums_mips64[] = {
+    fpr_f0_mips64,      fpr_f1_mips64,  fpr_f2_mips64,  fpr_f3_mips64,
+    fpr_f4_mips64,      fpr_f5_mips64,  fpr_f6_mips64,  fpr_f7_mips64,
+    fpr_f8_mips64,      fpr_f9_mips64,  fpr_f10_mips64, fpr_f11_mips64,
+    fpr_f12_mips64,     fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64,
+    fpr_f16_mips64,     fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64,
+    fpr_f20_mips64,     fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64,
+    fpr_f24_mips64,     fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64,
+    fpr_f28_mips64,     fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64,
+    fpr_fcsr_mips64,    fpr_fir_mips64,
+    LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) -
+                      1 ==
+                  k_num_fpr_registers_mips64,
+              "g_fp_regnums_mips64 has wrong number of register infos");
 
 // Number of register sets provided by this context.
-constexpr size_t k_num_register_sets = 1;
+constexpr size_t k_num_register_sets = 2;
 
 static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
     {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
-     g_gpr_regnums},
+     g_gp_regnums_mips64},
+    {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64,
+     g_fp_regnums_mips64},
 };
 
-
 // http://svnweb.freebsd.org/base/head/sys/mips/include/regnum.h
 typedef struct _GPR {
   uint64_t zero;
@@ -79,6 +105,43 @@ typedef struct _GPR {
   uint64_t dummy;
 } GPR_freebsd_mips;
 
+typedef struct _FPR {
+  uint64_t f0;
+  uint64_t f1;
+  uint64_t f2;
+  uint64_t f3;
+  uint64_t f4;
+  uint64_t f5;
+  uint64_t f6;
+  uint64_t f7;
+  uint64_t f8;
+  uint64_t f9;
+  uint64_t f10;
+  uint64_t f11;
+  uint64_t f12;
+  uint64_t f13;
+  uint64_t f14;
+  uint64_t f15;
+  uint64_t f16;
+  uint64_t f17;
+  uint64_t f18;
+  uint64_t f19;
+  uint64_t f20;
+  uint64_t f21;
+  uint64_t f22;
+  uint64_t f23;
+  uint64_t f24;
+  uint64_t f25;
+  uint64_t f26;
+  uint64_t f27;
+  uint64_t f28;
+  uint64_t f29;
+  uint64_t f30;
+  uint64_t f31;
+  uint64_t fcsr;
+  uint64_t fir;
+} FPR_freebsd_mips;
+
 // Include RegisterInfos_mips64 to declare our g_register_infos_mips64
 // structure.
 #define DECLARE_REGISTER_INFOS_MIPS64_STRUCT
@@ -95,14 +158,13 @@ size_t RegisterContextFreeBSD_mips64::GetGPRSize() const {
 
 const RegisterSet *
 RegisterContextFreeBSD_mips64::GetRegisterSet(size_t set) const {
-   // Check if RegisterSet is available
-   if (set < k_num_register_sets)
-     return &g_reg_sets_mips64[set];
-   return nullptr;
+  // Check if RegisterSet is available
+  if (set < k_num_register_sets)
+    return &g_reg_sets_mips64[set];
+  return nullptr;
 }
 
-size_t
-RegisterContextFreeBSD_mips64::GetRegisterSetCount() const {
+size_t RegisterContextFreeBSD_mips64::GetRegisterSetCount() const {
   return k_num_register_sets;
 }
 

diff  --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h
index b28b91810e48..32a8c98fce43 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h
@@ -11,12 +11,16 @@
 #include "lldb/Core/dwarf.h"
 #include "llvm/Support/Compiler.h"
 
-
 #ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
 
 // Computes the offset of the given GPR in the user data area.
 #define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR_freebsd_mips, regname))
 
+// Computes the offset of the given FPR in the extended data area.
+#define FPR_OFFSET(regname)                                                    \
+  (sizeof(GPR_freebsd_mips) +                                                  \
+   LLVM_EXTENSION offsetof(FPR_freebsd_mips, regname))
+
 // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB
 
 // Note that the size and offset will be updated by platform-specific classes.
@@ -29,6 +33,31 @@
                                   NULL, NULL, NULL, 0                          \
   }
 
+const uint8_t dwarf_opcode_mips64[] = {
+    llvm::dwarf::DW_OP_regx,  dwarf_sr_mips64,        llvm::dwarf::DW_OP_lit1,
+    llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and,
+    llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr};
+
+#define DEFINE_FPR(reg, alt, kind1, kind2, kind3)                              \
+  {                                                                            \
+    #reg, alt, sizeof(((FPR_freebsd_mips *) 0)->reg),                          \
+                      FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat,         \
+                                 {kind1, kind2, kind3, LLDB_INVALID_REGNUM,    \
+                                  fpr_##reg##_mips64 },                        \
+                                  NULL, NULL, dwarf_opcode_mips64,             \
+                                  sizeof(dwarf_opcode_mips64)                  \
+  }
+
+#define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3)                         \
+  {                                                                            \
+    #reg, alt, sizeof(((FPR_freebsd_mips *) 0)->reg),                          \
+                      FPR_OFFSET(reg), eEncodingUint, eFormatHex,              \
+                                 {kind1, kind2, kind3, LLDB_INVALID_REGNUM,    \
+                                  fpr_##reg##_mips64 },                        \
+                                  NULL, NULL, NULL, 0                          \
+  }
+
+
 static RegisterInfo g_register_infos_mips64[] = {
 // General purpose registers.            EH_Frame,                  DWARF,
 // Generic,    Process Plugin
@@ -112,6 +141,75 @@ static RegisterInfo g_register_infos_mips64[] = {
                LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
     DEFINE_GPR(dummy, nullptr, dwarf_dummy_mips64, dwarf_dummy_mips64,
                LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+    DEFINE_FPR(f0, nullptr, dwarf_f0_mips64, dwarf_f0_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f1, nullptr, dwarf_f1_mips64, dwarf_f1_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f2, nullptr, dwarf_f2_mips64, dwarf_f2_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f3, nullptr, dwarf_f3_mips64, dwarf_f3_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f4, nullptr, dwarf_f4_mips64, dwarf_f4_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f5, nullptr, dwarf_f5_mips64, dwarf_f5_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f6, nullptr, dwarf_f6_mips64, dwarf_f6_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f7, nullptr, dwarf_f7_mips64, dwarf_f7_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f8, nullptr, dwarf_f8_mips64, dwarf_f8_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f9, nullptr, dwarf_f9_mips64, dwarf_f9_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f10, nullptr, dwarf_f10_mips64, dwarf_f10_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f11, nullptr, dwarf_f11_mips64, dwarf_f11_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f12, nullptr, dwarf_f12_mips64, dwarf_f12_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f13, nullptr, dwarf_f13_mips64, dwarf_f13_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f14, nullptr, dwarf_f14_mips64, dwarf_f14_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f15, nullptr, dwarf_f15_mips64, dwarf_f15_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f16, nullptr, dwarf_f16_mips64, dwarf_f16_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f17, nullptr, dwarf_f17_mips64, dwarf_f17_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f18, nullptr, dwarf_f18_mips64, dwarf_f18_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f19, nullptr, dwarf_f19_mips64, dwarf_f19_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f20, nullptr, dwarf_f20_mips64, dwarf_f20_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f21, nullptr, dwarf_f21_mips64, dwarf_f21_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f22, nullptr, dwarf_f22_mips64, dwarf_f22_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f23, nullptr, dwarf_f23_mips64, dwarf_f23_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f24, nullptr, dwarf_f24_mips64, dwarf_f24_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f25, nullptr, dwarf_f25_mips64, dwarf_f25_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f26, nullptr, dwarf_f26_mips64, dwarf_f26_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f27, nullptr, dwarf_f27_mips64, dwarf_f27_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f28, nullptr, dwarf_f28_mips64, dwarf_f28_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f29, nullptr, dwarf_f29_mips64, dwarf_f29_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f30, nullptr, dwarf_f30_mips64, dwarf_f30_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR(f31, nullptr, dwarf_f31_mips64, dwarf_f31_mips64,
+               LLDB_INVALID_REGNUM),
+    DEFINE_FPR_INFO(fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64,
+                    LLDB_INVALID_REGNUM),
+    DEFINE_FPR_INFO(fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64,
+                    LLDB_INVALID_REGNUM),
 };
 
 static_assert((sizeof(g_register_infos_mips64) /

diff  --git a/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
index e6a7efd00f67..000f6e3847e7 100644
--- a/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
+++ b/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h
@@ -57,9 +57,47 @@ enum {
   gpr_dummy_mips64,
   k_last_gpr_mips64 = gpr_dummy_mips64,
 
+  k_first_fpr_mips64,
+  fpr_f0_mips64 = k_first_fpr_mips64,
+  fpr_f1_mips64,
+  fpr_f2_mips64,
+  fpr_f3_mips64,
+  fpr_f4_mips64,
+  fpr_f5_mips64,
+  fpr_f6_mips64,
+  fpr_f7_mips64,
+  fpr_f8_mips64,
+  fpr_f9_mips64,
+  fpr_f10_mips64,
+  fpr_f11_mips64,
+  fpr_f12_mips64,
+  fpr_f13_mips64,
+  fpr_f14_mips64,
+  fpr_f15_mips64,
+  fpr_f16_mips64,
+  fpr_f17_mips64,
+  fpr_f18_mips64,
+  fpr_f19_mips64,
+  fpr_f20_mips64,
+  fpr_f21_mips64,
+  fpr_f22_mips64,
+  fpr_f23_mips64,
+  fpr_f24_mips64,
+  fpr_f25_mips64,
+  fpr_f26_mips64,
+  fpr_f27_mips64,
+  fpr_f28_mips64,
+  fpr_f29_mips64,
+  fpr_f30_mips64,
+  fpr_f31_mips64,
+  fpr_fcsr_mips64,
+  fpr_fir_mips64,
+  k_last_fpr_mips64 = fpr_fir_mips64,
+
   k_num_registers_mips64,
 
-  k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1
+  k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1,
+  k_num_fpr_registers_mips64 = k_last_fpr_mips64 - k_first_fpr_mips64 + 1,
 };
-}
+} // namespace lldb_private
 #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H

diff  --git a/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp b/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
index f14dc8faaea3..2d2c183a0c55 100644
--- a/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
+++ b/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
@@ -409,6 +409,11 @@ TEST(RegisterContextFreeBSDTest, arm64) {
   EXPECT_THAT(GetRegParams(reg_ctx, gpr_##lldb_reg##_mips64),                  \
               ::testing::Pair(offsetof(reg, r_regs[fbsd_regno]),               \
                               sizeof(reg::r_regs[fbsd_regno])))
+#define EXPECT_FPU_MIPS64(lldb_reg, fbsd_regno)                                \
+  EXPECT_THAT(                                                                 \
+      GetRegParams(reg_ctx, fpr_##lldb_reg##_mips64),                          \
+      ::testing::Pair(offsetof(fpreg, r_regs[fbsd_regno]) + base_offset,       \
+                      sizeof(fpreg::r_regs[fbsd_regno])))
 
 TEST(RegisterContextFreeBSDTest, mips64) {
   ArchSpec arch{"mips64-unknown-freebsd"};
@@ -457,6 +462,10 @@ TEST(RegisterContextFreeBSDTest, mips64) {
   EXPECT_GPR_MIPS64(pc, 37);
   EXPECT_GPR_MIPS64(ic, 38);
   EXPECT_GPR_MIPS64(dummy, 39);
+
+  size_t base_offset = reg_ctx.GetRegisterInfo()[fpr_f0_mips64].byte_offset;
+
+  EXPECT_FPU_MIPS64(f0, 0);
 }
 
 #endif // defined(__mips64__)


        


More information about the lldb-commits mailing list