* [PATCH v1] PowerPC: Add support for Dense Math registers (RFC02653)
@ 2026-09-24 6:30 Abhay Kandpal
2026-09-25 12:05 ` Ulrich Weigand
0 siblings, 1 reply; 4+ messages in thread
From: Abhay Kandpal @ 2026-09-24 6:30 UTC (permalink / raw)
To: gdb-patches; +Cc: Ulrich.Weigand, cel, abhay.k, Abhay Kandpal
This patch adds support for the Dense Math Registers (DMR) available
on a future PowerPC processor for the powerpc linux native and core
file targets, and for the powerpc linux server stub.
Eight 1024-bit DMR registers are provided. Each DMR contains eight
128-bit rows. DMR registers are accessed via PTRACE_GETDMREGS and
PTRACE_SETDMREGS ptrace requests, which require the Dense Math
facility to be enabled in the kernel configuration.
A new target description (powerpc-dmr-vsx32l/64l) is introduced for
systems where DMR registers are available. The existing isa207 target
description is left unchanged so that systems without DMR support are
not affected. DMR availability is detected at runtime by probing the
kernel with PTRACE_GETDMREGS. On kernels without DMR support the
registers are gracefully skipped and show as unavailable.
The NT_PPC_DMR note type used for core files was added to binutils in
commit 6a25d73ee2ab ("PowerPC: Add NT_PPC_DMR core file support").
gdb/
* arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_DMRREGSET): Declare.
(ppc_linux_features): Add has_dmr field.
(ppc_linux_no_features): Initialize has_dmr to false.
* arch/ppc-linux-common.c (ppc_linux_match_description): Return
DMR target description when has_dmr is set.
* arch/ppc-linux-tdesc.h (tdesc_powerpc_dmr_vsx32l)
(tdesc_powerpc_dmr_vsx64l): Declare.
* features/Makefile: Add powerpc-dmr-vsx32l and
powerpc-dmr-vsx64l entries.
* features/rs6000/power-dmr.xml: New file.
* features/rs6000/powerpc-dmr-vsx32l.xml: New file.
* features/rs6000/powerpc-dmr-vsx64l.xml: New file.
* features/rs6000/powerpc-dmr-vsx32l.c: New generated file.
* features/rs6000/powerpc-dmr-vsx64l.c: New generated file.
* regformats/rs6000/powerpc-dmr-vsx32l.dat: New generated file.
* regformats/rs6000/powerpc-dmr-vsx64l.dat: New generated file.
* nat/ppc-linux.h (PTRACE_GETDMREGS, PTRACE_SETDMREGS): Define if
not already defined.
* ppc-linux-nat.c (fetch_register, fetch_ppc_registers): Use
PTRACE_GETDMREGS to fetch dmr regset.
(store_register, store_ppc_registers): Use PTRACE_SETDMREGS to
store dmr regset.
(ppc_linux_nat_target::read_description): Detect DMR availability
using PTRACE_GETDMREGS and set has_dmr field in features struct.
* ppc-linux-tdep.c (ppc32_regmap_dmr, ppc32_linux_dmrregset):
New globals.
(ppc_linux_iterate_over_regset_sections): Call back with the dmr
regset.
* ppc-linux-tdep.h (ppc32_linux_dmrregset): Declare.
* ppc-tdep.h (struct ppc_gdbarch_tdep) <have_dmr>: New field.
<ppc_dmr0_regnum>: New field.
(enum): <PPC_DMR0_REGNUM> through <PPC_DMR7_REGNUM>: New enum
values.
(PPC_IS_DMR_REGNUM): Define.
* rs6000-tdep.c (rs6000_gdbarch_init): Look for and validate the
dmr feature.
gdbserver/
* configure.srv (powerpc*-*-linux*): Add rs6000/power-dmr.xml,
powerpc-dmr-vsx32l.o and powerpc-dmr-vsx64l.o.
* linux-ppc-low.cc (ppc_fill_dmrregset, ppc_store_dmrregset):
New functions.
(ppc_regsets): Add entry for dmr regset.
(ppc_target::low_arch_setup): Detect DMR availability using
PTRACE_GETDMREGS and set has_dmr in features struct. Set size
for dmr regset.
(ppc_target::get_ipa_tdesc_idx): Return PPC_TDESC_DMR_VSX for
dmr target description.
* linux-ppc-ipa.cc (ppc_get_ipa_tdesc): Handle PPC_TDESC_DMR_VSX.
* linux-ppc-tdesc-init.h (PPC_TDESC_DMR_VSX): New enum value.
(init_registers_powerpc_dmr_vsx32l): Declare.
(init_registers_powerpc_dmr_vsx64l): Declare.
---
Tested on powerpc64le-linux. DMR register read, write, and core-file
round-trip verified on a system with the Dense Math facility enabled in
the kernel; graceful fallback verified on a kernel without it.
gdb/arch/ppc-linux-common.c | 13 +-
gdb/arch/ppc-linux-common.h | 3 +
gdb/arch/ppc-linux-tdesc.h | 2 +
gdb/features/Makefile | 4 +
gdb/features/rs6000/power-dmr.xml | 23 ++
gdb/features/rs6000/powerpc-dmr-vsx32l.c | 227 +++++++++++++++++++
gdb/features/rs6000/powerpc-dmr-vsx32l.xml | 20 ++
gdb/features/rs6000/powerpc-dmr-vsx64l.c | 227 +++++++++++++++++++
gdb/features/rs6000/powerpc-dmr-vsx64l.xml | 20 ++
gdb/nat/ppc-linux.h | 5 +
gdb/ppc-linux-nat.c | 58 +++++
gdb/ppc-linux-tdep.c | 33 +++
gdb/ppc-linux-tdep.h | 1 +
gdb/ppc-tdep.h | 20 ++
gdb/regformats/rs6000/powerpc-dmr-vsx32l.dat | 164 ++++++++++++++
gdb/regformats/rs6000/powerpc-dmr-vsx64l.dat | 164 ++++++++++++++
gdb/rs6000-tdep.c | 25 +-
gdbserver/configure.srv | 7 +-
gdbserver/linux-ppc-ipa.cc | 4 +
gdbserver/linux-ppc-low.cc | 48 ++++
gdbserver/linux-ppc-tdesc-init.h | 7 +
21 files changed, 1072 insertions(+), 3 deletions(-)
create mode 100644 gdb/features/rs6000/power-dmr.xml
create mode 100644 gdb/features/rs6000/powerpc-dmr-vsx32l.c
create mode 100644 gdb/features/rs6000/powerpc-dmr-vsx32l.xml
create mode 100644 gdb/features/rs6000/powerpc-dmr-vsx64l.c
create mode 100644 gdb/features/rs6000/powerpc-dmr-vsx64l.xml
create mode 100644 gdb/regformats/rs6000/powerpc-dmr-vsx32l.dat
create mode 100644 gdb/regformats/rs6000/powerpc-dmr-vsx64l.dat
diff --git a/gdb/arch/ppc-linux-common.c b/gdb/arch/ppc-linux-common.c
index d36bc369f9e..19ad0625661 100644
--- a/gdb/arch/ppc-linux-common.c
+++ b/gdb/arch/ppc-linux-common.c
@@ -49,8 +49,14 @@ ppc_linux_match_description (struct ppc_linux_features features)
if (features.wordsize == 8)
{
+ /* HTM was disabled on POWER9 and later hardware following the
+ transactional-memory erratum, so it does not coexist with the
+ Dense Math facility introduced on later processors. The htm
+ and has_dmr cases below are therefore mutually exclusive in
+ practice. */
if (features.vsx)
tdesc = (features.htm ? tdesc_powerpc_isa207_htm_vsx64l
+ : features.has_dmr ? tdesc_powerpc_dmr_vsx64l
: features.isa207 ? tdesc_powerpc_isa207_vsx64l
: features.ppr_dscr ? tdesc_powerpc_isa205_ppr_dscr_vsx64l
: features.isa205 ? tdesc_powerpc_isa205_vsx64l
@@ -65,9 +71,14 @@ ppc_linux_match_description (struct ppc_linux_features features)
else
{
gdb_assert (features.wordsize == 4);
-
+ /* HTM was disabled on POWER9 and later hardware following the
+ transactional-memory erratum, so it does not coexist with the
+ Dense Math facility introduced on later processors. The htm
+ and has_dmr cases below are therefore mutually exclusive in
+ practice. */
if (features.vsx)
tdesc = (features.htm ? tdesc_powerpc_isa207_htm_vsx32l
+ : features.has_dmr ? tdesc_powerpc_dmr_vsx32l
: features.isa207 ? tdesc_powerpc_isa207_vsx32l
: features.ppr_dscr ? tdesc_powerpc_isa205_ppr_dscr_vsx32l
: features.isa205 ? tdesc_powerpc_isa205_vsx32l
diff --git a/gdb/arch/ppc-linux-common.h b/gdb/arch/ppc-linux-common.h
index 658801808db..384c89006d2 100644
--- a/gdb/arch/ppc-linux-common.h
+++ b/gdb/arch/ppc-linux-common.h
@@ -44,6 +44,7 @@ struct target_desc;
#define PPC_LINUX_SIZEOF_CPPRREGSET 8
#define PPC_LINUX_SIZEOF_CDSCRREGSET 8
#define PPC_LINUX_SIZEOF_CTARREGSET 8
+#define PPC_LINUX_SIZEOF_DMRREGSET (8 * 128)
/* Check if the hwcap auxv entry indicates that isa205 is supported. */
bool ppc_linux_has_isa205 (CORE_ADDR hwcap);
@@ -58,6 +59,7 @@ struct ppc_linux_features
bool ppr_dscr;
bool isa207;
bool htm;
+ bool has_dmr;
};
/* Base value for ppc_linux_features variables. */
@@ -69,6 +71,7 @@ const struct ppc_linux_features ppc_linux_no_features = {
false,
false,
false,
+ false,
};
/* Return a target description that matches FEATURES. */
diff --git a/gdb/arch/ppc-linux-tdesc.h b/gdb/arch/ppc-linux-tdesc.h
index 0a61ed8691d..fec0c2f605d 100644
--- a/gdb/arch/ppc-linux-tdesc.h
+++ b/gdb/arch/ppc-linux-tdesc.h
@@ -33,6 +33,7 @@ extern const_target_desc_up tdesc_powerpc_isa205_vsx32l;
extern const_target_desc_up tdesc_powerpc_isa205_ppr_dscr_vsx32l;
extern const_target_desc_up tdesc_powerpc_isa207_vsx32l;
extern const_target_desc_up tdesc_powerpc_isa207_htm_vsx32l;
+extern const_target_desc_up tdesc_powerpc_dmr_vsx32l;
extern const_target_desc_up tdesc_powerpc_e500l;
extern const_target_desc_up tdesc_powerpc_64l;
@@ -44,5 +45,6 @@ extern const_target_desc_up tdesc_powerpc_isa205_vsx64l;
extern const_target_desc_up tdesc_powerpc_isa205_ppr_dscr_vsx64l;
extern const_target_desc_up tdesc_powerpc_isa207_vsx64l;
extern const_target_desc_up tdesc_powerpc_isa207_htm_vsx64l;
+extern const_target_desc_up tdesc_powerpc_dmr_vsx64l;
#endif /* GDB_ARCH_PPC_LINUX_TDESC_H */
diff --git a/gdb/features/Makefile b/gdb/features/Makefile
index 161a7453d66..40a56044e66 100644
--- a/gdb/features/Makefile
+++ b/gdb/features/Makefile
@@ -60,6 +60,8 @@ WHICH = mips-linux mips-dsp-linux \
rs6000/powerpc-isa207-vsx32l rs6000/powerpc-isa207-vsx64l \
rs6000/powerpc-isa207-htm-vsx32l \
rs6000/powerpc-isa207-htm-vsx64l \
+ rs6000/powerpc-dmr-vsx32l \
+ rs6000/powerpc-dmr-vsx64l \
s390-linux32 s390-linux64 s390x-linux64 \
s390-linux32v1 s390-linux64v1 s390x-linux64v1 \
s390-linux32v2 s390-linux64v2 s390x-linux64v2 \
@@ -144,6 +146,8 @@ XMLTOC = \
rs6000/powerpc-isa207-vsx64l.xml \
rs6000/powerpc-isa207-htm-vsx32l.xml \
rs6000/powerpc-isa207-htm-vsx64l.xml \
+ rs6000/powerpc-dmr-vsx32l.xml \
+ rs6000/powerpc-dmr-vsx64l.xml \
rs6000/powerpc-vsx32.xml \
rs6000/powerpc-vsx32l.xml \
rs6000/powerpc-vsx64.xml \
diff --git a/gdb/features/rs6000/power-dmr.xml b/gdb/features/rs6000/power-dmr.xml
new file mode 100644
index 00000000000..26343621de5
--- /dev/null
+++ b/gdb/features/rs6000/power-dmr.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2025-2026 Free Software Foundation, Inc.
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!-- Dense Math Registers. -->
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.power.dmr">
+
+ <!-- Define one 1024-bit vector composed of eight 128-bit lanes -->
+ <vector id="uint1024" type="uint128" count="8"/>
+
+ <!-- Eight 1024-bit Dense Math Registers -->
+ <reg name="dmr0" bitsize="1024" type="uint1024"/>
+ <reg name="dmr1" bitsize="1024" type="uint1024"/>
+ <reg name="dmr2" bitsize="1024" type="uint1024"/>
+ <reg name="dmr3" bitsize="1024" type="uint1024"/>
+ <reg name="dmr4" bitsize="1024" type="uint1024"/>
+ <reg name="dmr5" bitsize="1024" type="uint1024"/>
+ <reg name="dmr6" bitsize="1024" type="uint1024"/>
+ <reg name="dmr7" bitsize="1024" type="uint1024"/>
+</feature>
diff --git a/gdb/features/rs6000/powerpc-dmr-vsx32l.c b/gdb/features/rs6000/powerpc-dmr-vsx32l.c
new file mode 100644
index 00000000000..314833d231a
--- /dev/null
+++ b/gdb/features/rs6000/powerpc-dmr-vsx32l.c
@@ -0,0 +1,227 @@
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: powerpc-dmr-vsx32l.xml */
+
+#include "osabi.h"
+#include "target-descriptions.h"
+
+const_target_desc_up tdesc_powerpc_dmr_vsx32l;
+static void
+initialize_tdesc_powerpc_dmr_vsx32l (void)
+{
+ target_desc_up result = allocate_target_description ();
+ set_tdesc_architecture (result.get (), bfd_scan_arch ("powerpc:common"));
+
+ struct tdesc_feature *feature;
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.core");
+ tdesc_create_reg (feature, "r0", 0, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r2", 2, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r3", 3, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r4", 4, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r5", 5, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r6", 6, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r7", 7, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r8", 8, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r9", 9, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r10", 10, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r11", 11, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r12", 12, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r13", 13, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r14", 14, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r15", 15, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r16", 16, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r17", 17, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r18", 18, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r19", 19, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r20", 20, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r21", 21, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r22", 22, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r23", 23, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r24", 24, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r25", 25, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r26", 26, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r27", 27, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r28", 28, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r29", 29, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r30", 30, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "r31", 31, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "pc", 64, 1, NULL, 32, "code_ptr");
+ tdesc_create_reg (feature, "msr", 65, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "lr", 67, 1, NULL, 32, "code_ptr");
+ tdesc_create_reg (feature, "ctr", 68, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.fpu");
+ tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "fpscr", 70, 1, "float", 32, "int");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.linux");
+ tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 32, "int");
+ tdesc_create_reg (feature, "trap", 72, 1, NULL, 32, "int");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.altivec");
+ tdesc_type *element_type;
+ element_type = tdesc_named_type (feature, "ieee_single");
+ tdesc_create_vector (feature, "v4f", element_type, 4);
+
+ element_type = tdesc_named_type (feature, "int32");
+ tdesc_create_vector (feature, "v4i32", element_type, 4);
+
+ element_type = tdesc_named_type (feature, "int16");
+ tdesc_create_vector (feature, "v8i16", element_type, 8);
+
+ element_type = tdesc_named_type (feature, "int8");
+ tdesc_create_vector (feature, "v16i8", element_type, 16);
+
+ tdesc_type_with_fields *type_with_fields;
+ type_with_fields = tdesc_create_union (feature, "vec128");
+ tdesc_type *field_type;
+ field_type = tdesc_named_type (feature, "uint128");
+ tdesc_add_field (type_with_fields, "uint128", field_type);
+ field_type = tdesc_named_type (feature, "v4f");
+ tdesc_add_field (type_with_fields, "v4_float", field_type);
+ field_type = tdesc_named_type (feature, "v4i32");
+ tdesc_add_field (type_with_fields, "v4_int32", field_type);
+ field_type = tdesc_named_type (feature, "v8i16");
+ tdesc_add_field (type_with_fields, "v8_int16", field_type);
+ field_type = tdesc_named_type (feature, "v16i8");
+ tdesc_add_field (type_with_fields, "v16_int8", field_type);
+
+ tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int");
+ tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.vsx");
+ tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.ppr");
+ tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.dscr");
+ tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.tar");
+ tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.ebb");
+ tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.linux.pmu");
+ tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.dmr");
+ element_type = tdesc_named_type (feature, "uint128");
+ tdesc_create_vector (feature, "uint1024", element_type, 8);
+
+ tdesc_create_reg (feature, "dmr0", 150, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr1", 151, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr2", 152, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr3", 153, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr4", 154, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr5", 155, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr6", 156, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr7", 157, 1, NULL, 1024, "uint1024");
+
+ tdesc_powerpc_dmr_vsx32l = std::move (result);
+}
diff --git a/gdb/features/rs6000/powerpc-dmr-vsx32l.xml b/gdb/features/rs6000/powerpc-dmr-vsx32l.xml
new file mode 100644
index 00000000000..e1109f18865
--- /dev/null
+++ b/gdb/features/rs6000/powerpc-dmr-vsx32l.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2025-2026 Free Software Foundation, Inc.
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>powerpc:common</architecture>
+ <xi:include href="power-core.xml"/>
+ <xi:include href="power-fpu.xml"/>
+ <xi:include href="power-linux.xml"/>
+ <xi:include href="power-altivec.xml"/>
+ <xi:include href="power-vsx.xml"/>
+ <xi:include href="power-ppr.xml"/>
+ <xi:include href="power-dscr.xml"/>
+ <xi:include href="power-tar.xml"/>
+ <xi:include href="power-ebb.xml"/>
+ <xi:include href="power-linux-pmu.xml"/>
+ <xi:include href="power-dmr.xml"/>
+</target>
diff --git a/gdb/features/rs6000/powerpc-dmr-vsx64l.c b/gdb/features/rs6000/powerpc-dmr-vsx64l.c
new file mode 100644
index 00000000000..2da785fcba3
--- /dev/null
+++ b/gdb/features/rs6000/powerpc-dmr-vsx64l.c
@@ -0,0 +1,227 @@
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro:
+ Original: powerpc-dmr-vsx64l.xml */
+
+#include "osabi.h"
+#include "target-descriptions.h"
+
+const_target_desc_up tdesc_powerpc_dmr_vsx64l;
+static void
+initialize_tdesc_powerpc_dmr_vsx64l (void)
+{
+ target_desc_up result = allocate_target_description ();
+ set_tdesc_architecture (result.get (), bfd_scan_arch ("powerpc:common64"));
+
+ struct tdesc_feature *feature;
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.core");
+ tdesc_create_reg (feature, "r0", 0, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r1", 1, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r2", 2, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r3", 3, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r4", 4, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r5", 5, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r6", 6, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r7", 7, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r8", 8, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r9", 9, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r10", 10, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r11", 11, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r12", 12, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r13", 13, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r14", 14, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r15", 15, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r16", 16, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r17", 17, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r18", 18, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r19", 19, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r20", 20, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r21", 21, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r22", 22, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r23", 23, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r24", 24, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r25", 25, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r26", 26, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r27", 27, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r28", 28, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r29", 29, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r30", 30, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "r31", 31, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "pc", 64, 1, NULL, 64, "code_ptr");
+ tdesc_create_reg (feature, "msr", 65, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "cr", 66, 1, NULL, 32, "uint32");
+ tdesc_create_reg (feature, "lr", 67, 1, NULL, 64, "code_ptr");
+ tdesc_create_reg (feature, "ctr", 68, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "xer", 69, 1, NULL, 32, "uint32");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.fpu");
+ tdesc_create_reg (feature, "f0", 32, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f1", 33, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f2", 34, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f3", 35, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f4", 36, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f5", 37, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f6", 38, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f7", 39, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f8", 40, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f9", 41, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f10", 42, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f11", 43, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f12", 44, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f13", 45, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f14", 46, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f15", 47, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f16", 48, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f17", 49, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f18", 50, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f19", 51, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f20", 52, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f21", 53, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f22", 54, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f23", 55, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f24", 56, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f25", 57, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f26", 58, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f27", 59, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f28", 60, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f29", 61, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f30", 62, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "f31", 63, 1, NULL, 64, "ieee_double");
+ tdesc_create_reg (feature, "fpscr", 70, 1, "float", 64, "int");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.linux");
+ tdesc_create_reg (feature, "orig_r3", 71, 1, NULL, 64, "int");
+ tdesc_create_reg (feature, "trap", 72, 1, NULL, 64, "int");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.altivec");
+ tdesc_type *element_type;
+ element_type = tdesc_named_type (feature, "ieee_single");
+ tdesc_create_vector (feature, "v4f", element_type, 4);
+
+ element_type = tdesc_named_type (feature, "int32");
+ tdesc_create_vector (feature, "v4i32", element_type, 4);
+
+ element_type = tdesc_named_type (feature, "int16");
+ tdesc_create_vector (feature, "v8i16", element_type, 8);
+
+ element_type = tdesc_named_type (feature, "int8");
+ tdesc_create_vector (feature, "v16i8", element_type, 16);
+
+ tdesc_type_with_fields *type_with_fields;
+ type_with_fields = tdesc_create_union (feature, "vec128");
+ tdesc_type *field_type;
+ field_type = tdesc_named_type (feature, "uint128");
+ tdesc_add_field (type_with_fields, "uint128", field_type);
+ field_type = tdesc_named_type (feature, "v4f");
+ tdesc_add_field (type_with_fields, "v4_float", field_type);
+ field_type = tdesc_named_type (feature, "v4i32");
+ tdesc_add_field (type_with_fields, "v4_int32", field_type);
+ field_type = tdesc_named_type (feature, "v8i16");
+ tdesc_add_field (type_with_fields, "v8_int16", field_type);
+ field_type = tdesc_named_type (feature, "v16i8");
+ tdesc_add_field (type_with_fields, "v16_int8", field_type);
+
+ tdesc_create_reg (feature, "vr0", 73, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr1", 74, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr2", 75, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr3", 76, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr4", 77, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr5", 78, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr6", 79, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr7", 80, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr8", 81, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr9", 82, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr10", 83, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr11", 84, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr12", 85, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr13", 86, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr14", 87, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr15", 88, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr16", 89, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr17", 90, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr18", 91, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr19", 92, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr20", 93, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr21", 94, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr22", 95, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr23", 96, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr24", 97, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr25", 98, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr26", 99, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr27", 100, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr28", 101, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr29", 102, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr30", 103, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vr31", 104, 1, NULL, 128, "vec128");
+ tdesc_create_reg (feature, "vscr", 105, 1, "vector", 32, "int");
+ tdesc_create_reg (feature, "vrsave", 106, 1, "vector", 32, "int");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.vsx");
+ tdesc_create_reg (feature, "vs0h", 107, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs1h", 108, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs2h", 109, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs3h", 110, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs4h", 111, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs5h", 112, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs6h", 113, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs7h", 114, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs8h", 115, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs9h", 116, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs10h", 117, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs11h", 118, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs12h", 119, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs13h", 120, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs14h", 121, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs15h", 122, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs16h", 123, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs17h", 124, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs18h", 125, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs19h", 126, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs20h", 127, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs21h", 128, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs22h", 129, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs23h", 130, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs24h", 131, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs25h", 132, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs26h", 133, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs27h", 134, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs28h", 135, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs29h", 136, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs30h", 137, 1, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "vs31h", 138, 1, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.ppr");
+ tdesc_create_reg (feature, "ppr", 139, 1, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.dscr");
+ tdesc_create_reg (feature, "dscr", 140, 1, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.tar");
+ tdesc_create_reg (feature, "tar", 141, 1, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.ebb");
+ tdesc_create_reg (feature, "bescr", 142, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "ebbhr", 143, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "ebbrr", 144, 0, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.linux.pmu");
+ tdesc_create_reg (feature, "mmcr0", 145, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "mmcr2", 146, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "siar", 147, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "sdar", 148, 0, NULL, 64, "uint64");
+ tdesc_create_reg (feature, "sier", 149, 0, NULL, 64, "uint64");
+
+ feature = tdesc_create_feature (result.get (), "org.gnu.gdb.power.dmr");
+ element_type = tdesc_named_type (feature, "uint128");
+ tdesc_create_vector (feature, "uint1024", element_type, 8);
+
+ tdesc_create_reg (feature, "dmr0", 150, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr1", 151, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr2", 152, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr3", 153, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr4", 154, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr5", 155, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr6", 156, 1, NULL, 1024, "uint1024");
+ tdesc_create_reg (feature, "dmr7", 157, 1, NULL, 1024, "uint1024");
+
+ tdesc_powerpc_dmr_vsx64l = std::move (result);
+}
diff --git a/gdb/features/rs6000/powerpc-dmr-vsx64l.xml b/gdb/features/rs6000/powerpc-dmr-vsx64l.xml
new file mode 100644
index 00000000000..f3a88b7180b
--- /dev/null
+++ b/gdb/features/rs6000/powerpc-dmr-vsx64l.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2025-2026 Free Software Foundation, Inc.
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>powerpc:common64</architecture>
+ <xi:include href="power64-core.xml"/>
+ <xi:include href="power-fpu-isa205.xml"/>
+ <xi:include href="power64-linux.xml"/>
+ <xi:include href="power-altivec.xml"/>
+ <xi:include href="power-vsx.xml"/>
+ <xi:include href="power-ppr.xml"/>
+ <xi:include href="power-dscr.xml"/>
+ <xi:include href="power-tar.xml"/>
+ <xi:include href="power-ebb.xml"/>
+ <xi:include href="power-linux-pmu.xml"/>
+ <xi:include href="power-dmr.xml"/>
+</target>
diff --git a/gdb/nat/ppc-linux.h b/gdb/nat/ppc-linux.h
index 26b9af4e298..5de42f00f18 100644
--- a/gdb/nat/ppc-linux.h
+++ b/gdb/nat/ppc-linux.h
@@ -159,6 +159,11 @@
#define NT_PPC_TM_CDSCR 0x10f
#endif
+#ifndef PTRACE_GETDMREGS
+#define PTRACE_GETDMREGS 0x1f
+#define PTRACE_SETDMREGS 0x20
+#endif
+
/* Return the wordsize of the target, either 4 or 8 bytes. */
int ppc_linux_target_wordsize (int tid);
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index 413e0e0ab97..1212e7ff6c4 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -1064,6 +1064,18 @@ fetch_register (struct regcache *regcache, int tid, int regno)
&ppc32_linux_ctarregset);
return;
}
+ else if (PPC_IS_DMR_REGNUM (regno))
+ {
+ gdb_assert (tdep->have_dmr);
+
+ gdb_byte dmr_buf[PPC_LINUX_SIZEOF_DMRREGSET];
+ if (ptrace (PTRACE_GETDMREGS, tid, 0, dmr_buf) >= 0)
+ ppc32_linux_dmrregset.supply_regset (&ppc32_linux_dmrregset,
+ regcache, regno,
+ dmr_buf,
+ PPC_LINUX_SIZEOF_DMRREGSET);
+ return;
+ }
if (regaddr == -1)
{
@@ -1304,6 +1316,16 @@ fetch_ppc_registers (struct regcache *regcache, int tid)
fetch_regset (regcache, tid, NT_PPC_TM_CVSX,
PPC_LINUX_SIZEOF_CVSXREGSET,
&ppc32_linux_cvsxregset);
+
+ if (tdep->have_dmr)
+ {
+ gdb_byte buf[PPC_LINUX_SIZEOF_DMRREGSET];
+ if (ptrace (PTRACE_GETDMREGS, tid, 0, buf) >= 0)
+ ppc32_linux_dmrregset.supply_regset (&ppc32_linux_dmrregset,
+ regcache, -1,
+ buf,
+ PPC_LINUX_SIZEOF_DMRREGSET);
+ }
if (tdep->ppc_cppr_regnum != -1)
fetch_regset (regcache, tid, NT_PPC_TM_CPPR,
PPC_LINUX_SIZEOF_CPPRREGSET,
@@ -1617,6 +1639,22 @@ store_register (const struct regcache *regcache, int tid, int regno)
&ppc32_linux_ctarregset);
return;
}
+ else if (PPC_IS_DMR_REGNUM (regno))
+ {
+ gdb_assert (tdep->have_dmr);
+
+ gdb_byte dmr_buf[PPC_LINUX_SIZEOF_DMRREGSET];
+ if (ptrace (PTRACE_GETDMREGS, tid, 0, dmr_buf) < 0)
+ perror_with_name (_("Couldn't read Dense Math registers"));
+
+ ppc32_linux_dmrregset.collect_regset (&ppc32_linux_dmrregset,
+ regcache, regno,
+ dmr_buf,
+ PPC_LINUX_SIZEOF_DMRREGSET);
+ if (ptrace (PTRACE_SETDMREGS, tid, 0, dmr_buf) < 0)
+ perror_with_name (_("Couldn't write Dense Math registers"));
+ return;
+ }
if (regaddr == -1)
return;
@@ -1851,6 +1889,18 @@ store_ppc_registers (const struct regcache *regcache, int tid)
PPC_LINUX_SIZEOF_TM_SPRREGSET,
&ppc32_linux_tm_sprregset);
+ if (tdep->have_dmr)
+ {
+ gdb_byte buf[PPC_LINUX_SIZEOF_DMRREGSET];
+ if (ptrace (PTRACE_GETDMREGS, tid, 0, buf) >= 0)
+ {
+ ppc32_linux_dmrregset.collect_regset (&ppc32_linux_dmrregset,
+ regcache, -1,
+ buf,
+ PPC_LINUX_SIZEOF_DMRREGSET);
+ ptrace (PTRACE_SETDMREGS, tid, 0, buf);
+ }
+ }
/* Because the EBB and checkpointed HTM registers can be
unavailable, attempts to store them here would cause this
function to fail most of the time, so we ignore them. */
@@ -2020,6 +2070,14 @@ ppc_linux_nat_target::read_description ()
}
}
+ /* Check whether the kernel supports Dense Math registers. Native
+ GDB accesses DMR through the dedicated PTRACE_GETDMREGS request. */
+ {
+ gdb_byte buf[PPC_LINUX_SIZEOF_DMRREGSET];
+ if (ptrace (PTRACE_GETDMREGS, tid, 0, buf) >= 0)
+ features.has_dmr = true;
+ }
+
return ppc_linux_match_description (features);
}
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index b468dbcb62c..edb2458d456 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -83,6 +83,8 @@
#include "features/rs6000/powerpc-isa205-ppr-dscr-vsx64l.c"
#include "features/rs6000/powerpc-isa207-vsx64l.c"
#include "features/rs6000/powerpc-isa207-htm-vsx64l.c"
+#include "features/rs6000/powerpc-dmr-vsx32l.c"
+#include "features/rs6000/powerpc-dmr-vsx64l.c"
#include "features/rs6000/powerpc-e500l.c"
#include "dwarf2/frame.h"
@@ -660,6 +662,30 @@ const struct regset ppc32_linux_pmuregset = {
regcache_collect_regset
};
+/* Dense Math Register map. */
+
+static const struct regcache_map_entry ppc32_regmap_dmr[] =
+ {
+ /* Each DMR register is 128 bytes (1024 bits). */
+ { 1, PPC_DMR0_REGNUM, 128 },
+ { 1, PPC_DMR1_REGNUM, 128 },
+ { 1, PPC_DMR2_REGNUM, 128 },
+ { 1, PPC_DMR3_REGNUM, 128 },
+ { 1, PPC_DMR4_REGNUM, 128 },
+ { 1, PPC_DMR5_REGNUM, 128 },
+ { 1, PPC_DMR6_REGNUM, 128 },
+ { 1, PPC_DMR7_REGNUM, 128 },
+ { 0 }
+ };
+
+/* Dense Math Register set. */
+
+const struct regset ppc32_linux_dmrregset = {
+ ppc32_regmap_dmr,
+ regcache_supply_regset,
+ regcache_collect_regset
+};
+
/* Hardware Transactional Memory special-purpose register regmap. */
static const struct regcache_map_entry ppc32_regmap_tm_spr[] =
@@ -1074,6 +1100,11 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
"Hardware Transactional Memory Special Purpose Registers",
cb_data);
+ if (tdep->have_dmr)
+ cb (".reg-ppc-dmr", PPC_LINUX_SIZEOF_DMRREGSET,
+ PPC_LINUX_SIZEOF_DMRREGSET,
+ &ppc32_linux_dmrregset, "Dense Math Registers", cb_data);
+
/* Checkpointed registers can be unavailable, don't call back if
we are generating a core file. */
@@ -2414,6 +2445,7 @@ INIT_GDB_FILE (ppc_linux_tdep)
initialize_tdesc_powerpc_isa205_ppr_dscr_vsx32l ();
initialize_tdesc_powerpc_isa207_vsx32l ();
initialize_tdesc_powerpc_isa207_htm_vsx32l ();
+ initialize_tdesc_powerpc_dmr_vsx32l ();
initialize_tdesc_powerpc_64l ();
initialize_tdesc_powerpc_altivec64l ();
initialize_tdesc_powerpc_vsx64l ();
@@ -2423,5 +2455,6 @@ INIT_GDB_FILE (ppc_linux_tdep)
initialize_tdesc_powerpc_isa205_ppr_dscr_vsx64l ();
initialize_tdesc_powerpc_isa207_vsx64l ();
initialize_tdesc_powerpc_isa207_htm_vsx64l ();
+ initialize_tdesc_powerpc_dmr_vsx64l ();
initialize_tdesc_powerpc_e500l ();
}
diff --git a/gdb/ppc-linux-tdep.h b/gdb/ppc-linux-tdep.h
index 2f99d7dc404..4f91caa2afd 100644
--- a/gdb/ppc-linux-tdep.h
+++ b/gdb/ppc-linux-tdep.h
@@ -64,5 +64,6 @@ extern const struct regset ppc32_linux_cvsxregset;
extern const struct regset ppc32_linux_cpprregset;
extern const struct regset ppc32_linux_cdscrregset;
extern const struct regset ppc32_linux_ctarregset;
+extern const struct regset ppc32_linux_dmrregset;
#endif /* GDB_PPC_LINUX_TDEP_H */
diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h
index 4dd20413125..2703a6b3345 100644
--- a/gdb/ppc-tdep.h
+++ b/gdb/ppc-tdep.h
@@ -282,6 +282,14 @@ struct ppc_gdbarch_tdep : gdbarch_tdep_base
int ppc_sdar_regnum = 0;
int ppc_sier_regnum = 0;
+ /* Dense Math registers. */
+ int have_dmr = 0;
+ /* Register number of dmr0, or -1 if DMR is not available. Set
+ from PPC_DMR0_REGNUM when the target provides the dmr feature.
+ Provided for register-offset computations (e.g. core file and
+ pseudo-register handling) added in follow-up DMR work. */
+ int ppc_dmr0_regnum = 0;
+
/* Hardware Transactional Memory registers. */
int have_htm_spr = 0;
int have_htm_core = 0;
@@ -389,6 +397,16 @@ enum {
PPC_CPPR_REGNUM = 321,
PPC_CDSCR_REGNUM = 322,
PPC_CTAR_REGNUM = 323,
+
+ /* Dense Math Registers (DMR). */
+ PPC_DMR0_REGNUM = 324,
+ PPC_DMR1_REGNUM,
+ PPC_DMR2_REGNUM,
+ PPC_DMR3_REGNUM,
+ PPC_DMR4_REGNUM,
+ PPC_DMR5_REGNUM,
+ PPC_DMR6_REGNUM,
+ PPC_DMR7_REGNUM,
PPC_NUM_REGS
};
@@ -416,6 +434,8 @@ enum {
#define PPC_IS_CKPTVSX_REGNUM(i) \
((i) >= PPC_CVSR0_UPPER_REGNUM && (i) < (PPC_CVSR0_UPPER_REGNUM + 32))
+#define PPC_IS_DMR_REGNUM(i) ((i) >= PPC_DMR0_REGNUM && (i) <= PPC_DMR7_REGNUM)
+
/* An instruction to match. */
struct ppc_insn_pattern
diff --git a/gdb/regformats/rs6000/powerpc-dmr-vsx32l.dat b/gdb/regformats/rs6000/powerpc-dmr-vsx32l.dat
new file mode 100644
index 00000000000..241347d7c8b
--- /dev/null
+++ b/gdb/regformats/rs6000/powerpc-dmr-vsx32l.dat
@@ -0,0 +1,164 @@
+# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
+# Generated from: rs6000/powerpc-dmr-vsx32l.xml
+name:powerpc_dmr_vsx32l
+xmltarget:powerpc-dmr-vsx32l.xml
+expedite:r1,pc
+osabi:unknown
+32:r0
+32:r1
+32:r2
+32:r3
+32:r4
+32:r5
+32:r6
+32:r7
+32:r8
+32:r9
+32:r10
+32:r11
+32:r12
+32:r13
+32:r14
+32:r15
+32:r16
+32:r17
+32:r18
+32:r19
+32:r20
+32:r21
+32:r22
+32:r23
+32:r24
+32:r25
+32:r26
+32:r27
+32:r28
+32:r29
+32:r30
+32:r31
+64:f0
+64:f1
+64:f2
+64:f3
+64:f4
+64:f5
+64:f6
+64:f7
+64:f8
+64:f9
+64:f10
+64:f11
+64:f12
+64:f13
+64:f14
+64:f15
+64:f16
+64:f17
+64:f18
+64:f19
+64:f20
+64:f21
+64:f22
+64:f23
+64:f24
+64:f25
+64:f26
+64:f27
+64:f28
+64:f29
+64:f30
+64:f31
+32:pc
+32:msr
+32:cr
+32:lr
+32:ctr
+32:xer
+32:fpscr
+32:orig_r3
+32:trap
+128:vr0
+128:vr1
+128:vr2
+128:vr3
+128:vr4
+128:vr5
+128:vr6
+128:vr7
+128:vr8
+128:vr9
+128:vr10
+128:vr11
+128:vr12
+128:vr13
+128:vr14
+128:vr15
+128:vr16
+128:vr17
+128:vr18
+128:vr19
+128:vr20
+128:vr21
+128:vr22
+128:vr23
+128:vr24
+128:vr25
+128:vr26
+128:vr27
+128:vr28
+128:vr29
+128:vr30
+128:vr31
+32:vscr
+32:vrsave
+64:vs0h
+64:vs1h
+64:vs2h
+64:vs3h
+64:vs4h
+64:vs5h
+64:vs6h
+64:vs7h
+64:vs8h
+64:vs9h
+64:vs10h
+64:vs11h
+64:vs12h
+64:vs13h
+64:vs14h
+64:vs15h
+64:vs16h
+64:vs17h
+64:vs18h
+64:vs19h
+64:vs20h
+64:vs21h
+64:vs22h
+64:vs23h
+64:vs24h
+64:vs25h
+64:vs26h
+64:vs27h
+64:vs28h
+64:vs29h
+64:vs30h
+64:vs31h
+64:ppr
+64:dscr
+64:tar
+64:bescr
+64:ebbhr
+64:ebbrr
+64:mmcr0
+64:mmcr2
+64:siar
+64:sdar
+64:sier
+1024:dmr0
+1024:dmr1
+1024:dmr2
+1024:dmr3
+1024:dmr4
+1024:dmr5
+1024:dmr6
+1024:dmr7
diff --git a/gdb/regformats/rs6000/powerpc-dmr-vsx64l.dat b/gdb/regformats/rs6000/powerpc-dmr-vsx64l.dat
new file mode 100644
index 00000000000..71fba85e5c2
--- /dev/null
+++ b/gdb/regformats/rs6000/powerpc-dmr-vsx64l.dat
@@ -0,0 +1,164 @@
+# THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi :set ro:
+# Generated from: rs6000/powerpc-dmr-vsx64l.xml
+name:powerpc_dmr_vsx64l
+xmltarget:powerpc-dmr-vsx64l.xml
+expedite:r1,pc
+osabi:unknown
+64:r0
+64:r1
+64:r2
+64:r3
+64:r4
+64:r5
+64:r6
+64:r7
+64:r8
+64:r9
+64:r10
+64:r11
+64:r12
+64:r13
+64:r14
+64:r15
+64:r16
+64:r17
+64:r18
+64:r19
+64:r20
+64:r21
+64:r22
+64:r23
+64:r24
+64:r25
+64:r26
+64:r27
+64:r28
+64:r29
+64:r30
+64:r31
+64:f0
+64:f1
+64:f2
+64:f3
+64:f4
+64:f5
+64:f6
+64:f7
+64:f8
+64:f9
+64:f10
+64:f11
+64:f12
+64:f13
+64:f14
+64:f15
+64:f16
+64:f17
+64:f18
+64:f19
+64:f20
+64:f21
+64:f22
+64:f23
+64:f24
+64:f25
+64:f26
+64:f27
+64:f28
+64:f29
+64:f30
+64:f31
+64:pc
+64:msr
+32:cr
+64:lr
+64:ctr
+32:xer
+64:fpscr
+64:orig_r3
+64:trap
+128:vr0
+128:vr1
+128:vr2
+128:vr3
+128:vr4
+128:vr5
+128:vr6
+128:vr7
+128:vr8
+128:vr9
+128:vr10
+128:vr11
+128:vr12
+128:vr13
+128:vr14
+128:vr15
+128:vr16
+128:vr17
+128:vr18
+128:vr19
+128:vr20
+128:vr21
+128:vr22
+128:vr23
+128:vr24
+128:vr25
+128:vr26
+128:vr27
+128:vr28
+128:vr29
+128:vr30
+128:vr31
+32:vscr
+32:vrsave
+64:vs0h
+64:vs1h
+64:vs2h
+64:vs3h
+64:vs4h
+64:vs5h
+64:vs6h
+64:vs7h
+64:vs8h
+64:vs9h
+64:vs10h
+64:vs11h
+64:vs12h
+64:vs13h
+64:vs14h
+64:vs15h
+64:vs16h
+64:vs17h
+64:vs18h
+64:vs19h
+64:vs20h
+64:vs21h
+64:vs22h
+64:vs23h
+64:vs24h
+64:vs25h
+64:vs26h
+64:vs27h
+64:vs28h
+64:vs29h
+64:vs30h
+64:vs31h
+64:ppr
+64:dscr
+64:tar
+64:bescr
+64:ebbhr
+64:ebbrr
+64:mmcr0
+64:mmcr2
+64:siar
+64:sdar
+64:sier
+1024:dmr0
+1024:dmr1
+1024:dmr2
+1024:dmr3
+1024:dmr4
+1024:dmr5
+1024:dmr6
+1024:dmr7
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 05a4f1a371c..ce1e2079944 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -7553,7 +7553,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
int have_tar = 0, have_ebb = 0, have_pmu = 0, have_htm_spr = 0;
int have_htm_core = 0, have_htm_fpu = 0, have_htm_altivec = 0;
int have_htm_vsx = 0, have_htm_ppr = 0, have_htm_dscr = 0;
- int have_htm_tar = 0;
+ int have_htm_tar = 0, have_dmr = 0;
int tdesc_wordsize = -1;
const struct target_desc *tdesc = info.target_desc;
tdesc_arch_data_up tdesc_data;
@@ -7883,6 +7883,27 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
else
have_ebb = 0;
+ /* Dense Math Registers (DMR). */
+ feature = tdesc_find_feature (tdesc, "org.gnu.gdb.power.dmr");
+ if (feature != NULL)
+ {
+ static const char *const dmr_regs[] = {
+ "dmr0", "dmr1", "dmr2", "dmr3", "dmr4", "dmr5",
+ "dmr6", "dmr7"
+ };
+
+ valid_p = 1;
+ for (i = 0; i < ARRAY_SIZE (dmr_regs); i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+ PPC_DMR0_REGNUM + i,
+ dmr_regs[i]);
+ if (!valid_p)
+ return NULL;
+ have_dmr = 1;
+ }
+ else
+ have_dmr = 0;
+
/* Subset of the ISA 2.07 Performance Monitor Registers provided
by Linux. */
feature = tdesc_find_feature (tdesc,
@@ -8277,6 +8298,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->ppc_dscr_regnum = have_dscr ? PPC_DSCR_REGNUM : -1;
tdep->ppc_tar_regnum = have_tar ? PPC_TAR_REGNUM : -1;
tdep->have_ebb = have_ebb;
+ tdep->have_dmr = have_dmr;
/* If additional pmu registers are added, care must be taken when
setting new fields in the tdep below, to maintain compatibility
@@ -8290,6 +8312,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->ppc_siar_regnum = have_pmu ? PPC_SIAR_REGNUM : -1;
tdep->ppc_sdar_regnum = have_pmu ? PPC_SDAR_REGNUM : -1;
tdep->ppc_sier_regnum = have_pmu ? PPC_SIER_REGNUM : -1;
+ tdep->ppc_dmr0_regnum = have_dmr ? PPC_DMR0_REGNUM : -1;
tdep->have_htm_spr = have_htm_spr;
tdep->have_htm_core = have_htm_core;
diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv
index 7bdd92e3f82..ef71960b905 100644
--- a/gdbserver/configure.srv
+++ b/gdbserver/configure.srv
@@ -22,7 +22,7 @@
# srv_linux_usrregs Set to "yes" if we can get at registers via
# PTRACE_PEEKUSR / PTRACE_POKEUSR.
-ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-isa207-vsx32l-ipa.o powerpc-isa207-htm-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o powerpc-isa207-vsx64l-ipa.o powerpc-isa207-htm-vsx64l-ipa.o"
+ipa_ppc_linux_regobj="powerpc-32l-ipa.o powerpc-altivec32l-ipa.o powerpc-vsx32l-ipa.o powerpc-isa205-32l-ipa.o powerpc-isa205-altivec32l-ipa.o powerpc-isa205-vsx32l-ipa.o powerpc-isa205-ppr-dscr-vsx32l-ipa.o powerpc-isa207-vsx32l-ipa.o powerpc-isa207-htm-vsx32l-ipa.o powerpc-dmr-vsx32l-ipa.o powerpc-e500l-ipa.o powerpc-64l-ipa.o powerpc-altivec64l-ipa.o powerpc-vsx64l-ipa.o powerpc-isa205-64l-ipa.o powerpc-isa205-altivec64l-ipa.o powerpc-isa205-vsx64l-ipa.o powerpc-isa205-ppr-dscr-vsx64l-ipa.o powerpc-isa207-vsx64l-ipa.o powerpc-isa207-htm-vsx64l-ipa.o powerpc-dmr-vsx64l-ipa.o"
# Linux object files. This is so we don't have to repeat
# these files over and over again.
@@ -221,6 +221,7 @@ case "${gdbserver_host}" in
srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx32l.o"
srv_regobj="${srv_regobj} powerpc-isa207-vsx32l.o"
srv_regobj="${srv_regobj} powerpc-isa207-htm-vsx32l.o"
+ srv_regobj="${srv_regobj} powerpc-dmr-vsx32l.o"
srv_regobj="${srv_regobj} powerpc-e500l.o"
srv_regobj="${srv_regobj} powerpc-64l.o"
srv_regobj="${srv_regobj} powerpc-altivec64l.o"
@@ -231,6 +232,7 @@ case "${gdbserver_host}" in
srv_regobj="${srv_regobj} powerpc-isa205-ppr-dscr-vsx64l.o"
srv_regobj="${srv_regobj} powerpc-isa207-vsx64l.o"
srv_regobj="${srv_regobj} powerpc-isa207-htm-vsx64l.o"
+ srv_regobj="${srv_regobj} powerpc-dmr-vsx64l.o"
srv_tgtobj="$srv_linux_obj linux-ppc-low.o"
srv_tgtobj="${srv_tgtobj} nat/ppc-linux.o"
srv_tgtobj="${srv_tgtobj} arch/ppc-linux-common.o"
@@ -243,6 +245,7 @@ case "${gdbserver_host}" in
srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx32l.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-vsx32l.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-htm-vsx32l.xml"
+ srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-dmr-vsx32l.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power-altivec.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power-vsx.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power-core.xml"
@@ -253,6 +256,7 @@ case "${gdbserver_host}" in
srv_xmlfiles="${srv_xmlfiles} rs6000/power-ppr.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power-tar.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power-ebb.xml"
+ srv_xmlfiles="${srv_xmlfiles} rs6000/power-dmr.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power-linux-pmu.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-spr.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power-htm-core.xml"
@@ -273,6 +277,7 @@ case "${gdbserver_host}" in
srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa205-ppr-dscr-vsx64l.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-vsx64l.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-isa207-htm-vsx64l.xml"
+ srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-dmr-vsx64l.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power64-core.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power64-linux.xml"
srv_xmlfiles="${srv_xmlfiles} rs6000/power64-htm-core.xml"
diff --git a/gdbserver/linux-ppc-ipa.cc b/gdbserver/linux-ppc-ipa.cc
index 6e815d52434..0ab1280281f 100644
--- a/gdbserver/linux-ppc-ipa.cc
+++ b/gdbserver/linux-ppc-ipa.cc
@@ -194,6 +194,8 @@ get_ipa_tdesc (int idx)
return tdesc_powerpc_isa207_vsx64l.get ();
case PPC_TDESC_ISA207_HTM_VSX:
return tdesc_powerpc_isa207_htm_vsx64l.get ();
+ case PPC_TDESC_DMR_VSX:
+ return tdesc_powerpc_dmr_vsx64l.get ();
#else
case PPC_TDESC_BASE:
return tdesc_powerpc_32l.get ();
@@ -213,6 +215,8 @@ get_ipa_tdesc (int idx)
return tdesc_powerpc_isa207_vsx32l.get ();
case PPC_TDESC_ISA207_HTM_VSX:
return tdesc_powerpc_isa207_htm_vsx32l.get ();
+ case PPC_TDESC_DMR_VSX:
+ return tdesc_powerpc_dmr_vsx32l.get ();
case PPC_TDESC_E500:
return tdesc_powerpc_e500l.get ();
#endif
diff --git a/gdbserver/linux-ppc-low.cc b/gdbserver/linux-ppc-low.cc
index 6a2c4136041..67fbd3f9744 100644
--- a/gdbserver/linux-ppc-low.cc
+++ b/gdbserver/linux-ppc-low.cc
@@ -558,6 +558,34 @@ ppc_store_pmuregset (struct regcache *regcache, const void *buf)
supply_register_by_name (regcache, "mmcr0", ®set[32]);
}
+/* Dense Math Registers (DMR). */
+static const char *const dmr_names[] = {
+ "dmr0", "dmr1", "dmr2", "dmr3",
+ "dmr4", "dmr5", "dmr6", "dmr7"
+};
+
+/* Dense Math Register regset fill function. */
+
+static void
+ppc_fill_dmrregset (struct regcache *regcache, void *buf)
+{
+ char *regset = (char *) buf;
+
+ for (int i = 0; i < 8; i++)
+ collect_register_by_name (regcache, dmr_names[i], ®set[i * 128]);
+}
+
+/* Dense Math Register regset store function. */
+
+static void
+ppc_store_dmrregset (struct regcache *regcache, const void *buf)
+{
+ const char *regset = (const char *) buf;
+
+ for (int i = 0; i < 8; i++)
+ supply_register_by_name (regcache, dmr_names[i], ®set[i * 128]);
+}
+
/* Hardware Transactional Memory special-purpose register regset fill
function. */
@@ -831,6 +859,8 @@ static struct regset_info ppc_regsets[] = {
NULL, ppc_store_ebbregset },
{ PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PMU, 0, EXTENDED_REGS,
ppc_fill_pmuregset, ppc_store_pmuregset },
+ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_DMR, 0, EXTENDED_REGS,
+ ppc_fill_dmrregset, ppc_store_dmrregset },
{ PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_TAR, 0, EXTENDED_REGS,
ppc_fill_tarregset, ppc_store_tarregset },
{ PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PPC_PPR, 0, EXTENDED_REGS,
@@ -926,6 +956,14 @@ ppc_target::low_arch_setup ()
}
}
+ /* Check whether the kernel supports Dense Math registers. Native
+ GDB accesses DMR through the dedicated PTRACE_GETDMREGS request. */
+ {
+ gdb_byte buf[PPC_LINUX_SIZEOF_DMRREGSET];
+ if (ptrace (PTRACE_GETDMREGS, tid, 0, buf) >= 0)
+ features.has_dmr = true;
+ }
+
tdesc = ppc_linux_match_description (features);
/* On 32-bit machines, check for SPE registers.
@@ -990,6 +1028,10 @@ ppc_target::low_arch_setup ()
regset->size = (features.isa207 ?
PPC_LINUX_SIZEOF_PMUREGSET : 0);
break;
+ case NT_PPC_DMR:
+ regset->size = (features.has_dmr ?
+ PPC_LINUX_SIZEOF_DMRREGSET : 0);
+ break;
case NT_PPC_TM_SPR:
regset->size = (features.htm ?
PPC_LINUX_SIZEOF_TM_SPRREGSET : 0);
@@ -3415,6 +3457,8 @@ ppc_target::get_ipa_tdesc_idx ()
return PPC_TDESC_ISA207_VSX;
if (tdesc == tdesc_powerpc_isa207_htm_vsx64l.get ())
return PPC_TDESC_ISA207_HTM_VSX;
+ if (tdesc == tdesc_powerpc_dmr_vsx64l.get ())
+ return PPC_TDESC_DMR_VSX;
#endif
if (tdesc == tdesc_powerpc_32l.get ())
@@ -3435,6 +3479,8 @@ ppc_target::get_ipa_tdesc_idx ()
return PPC_TDESC_ISA207_VSX;
if (tdesc == tdesc_powerpc_isa207_htm_vsx32l.get ())
return PPC_TDESC_ISA207_HTM_VSX;
+ if (tdesc == tdesc_powerpc_dmr_vsx32l.get ())
+ return PPC_TDESC_DMR_VSX;
if (tdesc == tdesc_powerpc_e500l.get ())
return PPC_TDESC_E500;
@@ -3459,6 +3505,7 @@ initialize_low_arch (void)
init_registers_powerpc_isa205_ppr_dscr_vsx32l ();
init_registers_powerpc_isa207_vsx32l ();
init_registers_powerpc_isa207_htm_vsx32l ();
+ init_registers_powerpc_dmr_vsx32l ();
init_registers_powerpc_e500l ();
#if __powerpc64__
init_registers_powerpc_64l ();
@@ -3470,6 +3517,7 @@ initialize_low_arch (void)
init_registers_powerpc_isa205_ppr_dscr_vsx64l ();
init_registers_powerpc_isa207_vsx64l ();
init_registers_powerpc_isa207_htm_vsx64l ();
+ init_registers_powerpc_dmr_vsx64l ();
#endif
initialize_regsets_info (&ppc_regsets_info);
diff --git a/gdbserver/linux-ppc-tdesc-init.h b/gdbserver/linux-ppc-tdesc-init.h
index f7d220e88ad..f5b4defa0ed 100644
--- a/gdbserver/linux-ppc-tdesc-init.h
+++ b/gdbserver/linux-ppc-tdesc-init.h
@@ -35,6 +35,7 @@ enum ppc_linux_tdesc {
PPC_TDESC_ISA205_PPR_DSCR_VSX,
PPC_TDESC_ISA207_VSX,
PPC_TDESC_ISA207_HTM_VSX,
+ PPC_TDESC_DMR_VSX,
PPC_TDESC_E500,
};
@@ -67,6 +68,9 @@ void init_registers_powerpc_isa207_vsx32l (void);
/* Defined in auto-generated file powerpc-isa207-htm-vsx32l.c. */
void init_registers_powerpc_isa207_htm_vsx32l (void);
+/* Defined in auto-generated file powerpc-dmr-vsx32l.c. */
+void init_registers_powerpc_dmr_vsx32l (void);
+
/* Defined in auto-generated file powerpc-e500l.c. */
void init_registers_powerpc_e500l (void);
@@ -101,6 +105,9 @@ void init_registers_powerpc_isa207_vsx64l (void);
/* Defined in auto-generated file powerpc-isa207-htm-vsx64l.c. */
void init_registers_powerpc_isa207_htm_vsx64l (void);
+/* Defined in auto-generated file powerpc-dmr-vsx64l.c. */
+void init_registers_powerpc_dmr_vsx64l (void);
+
#endif
#endif /* GDBSERVER_LINUX_PPC_TDESC_INIT_H */
--
2.51.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v1] PowerPC: Add support for Dense Math registers (RFC02653)
2026-09-24 6:30 [PATCH v1] PowerPC: Add support for Dense Math registers (RFC02653) Abhay Kandpal
@ 2026-09-25 12:05 ` Ulrich Weigand
2026-09-26 9:34 ` Abhay Kandpal
0 siblings, 1 reply; 4+ messages in thread
From: Ulrich Weigand @ 2026-09-25 12:05 UTC (permalink / raw)
To: Abhay Kandpal, gdb-patches; +Cc: cel, Abhay Kandpal
Abhay Kandpal <abhay@linux.ibm.com> wrote:
>A new target description (powerpc-dmr-vsx32l/64l) is introduced for
>systems where DMR registers are available. The existing isa207 target
>description is left unchanged so that systems without DMR support are
>not affected. DMR availability is detected at runtime by probing the
>kernel with PTRACE_GETDMREGS. On kernels without DMR support the
>registers are gracefully skipped and show as unavailable.
This looks good in general. One question about naming: most recent
features have names that identify the base Power ISA level (isa205,
isa207, etc.). Should we follow this precedent for the new target
description name?
A few other comments below.
> if (features.wordsize == 8)
> {
>+ /* HTM was disabled on POWER9 and later hardware following the
>+ transactional-memory erratum, so it does not coexist with the
>+ Dense Math facility introduced on later processors. The htm
>+ and has_dmr cases below are therefore mutually exclusive in
>+ practice. */
> if (features.vsx)
> tdesc = (features.htm ? tdesc_powerpc_isa207_htm_vsx64l
>+ : features.has_dmr ? tdesc_powerpc_dmr_vsx64l
Even so, it would be preferable to add the newest feature first.
>@@ -58,6 +59,7 @@ struct ppc_linux_features
> bool ppr_dscr;
> bool isa207;
> bool htm;
>+ bool has_dmr;
For this struct, precedent is not to use the "has_" prefix.
>+ <!-- Define one 1024-bit vector composed of eight 128-bit lanes -->
>+ <vector id="uint1024" type="uint128" count="8"/>
"uint1024" is a surprising name for a vector type. I would have
expected something like "v8uint128" ?
>@@ -159,6 +159,11 @@
> #define NT_PPC_TM_CDSCR 0x10f
> #endif
>
>+#ifndef PTRACE_GETDMREGS
>+#define PTRACE_GETDMREGS 0x1f
>+#define PTRACE_SETDMREGS 0x20
>+#endif
Please move this block higher up, together with the
other PTRACE_ defines in this file.
That said, it would have been preferable to use the
regset mechanism like for all other recently added
registers, rather than a completely new PTRACE_ call.
I see in the gdbserver you actually do that! So please
use the same method in gdb itself as well.
>+ /* Check whether the kernel supports Dense Math registers. Native
>+ GDB accesses DMR through the dedicated PTRACE_GETDMREGS
request. */
>+ {
>+ gdb_byte buf[PPC_LINUX_SIZEOF_DMRREGSET];
>+ if (ptrace (PTRACE_GETDMREGS, tid, 0, buf) >= 0)
>+ features.has_dmr = true;
>+ }
Again it would be preferable to use a regset check instead.
Is there a HWCAP bit we should check in addition, to indicate that
the kernel and hypervisor support context-swapping these registers?
>+ /* Dense Math registers. */
>+ int have_dmr = 0;
>+ /* Register number of dmr0, or -1 if DMR is not available. Set
>+ from PPC_DMR0_REGNUM when the target provides the dmr feature.
>+ Provided for register-offset computations (e.g. core file and
>+ pseudo-register handling) added in follow-up DMR work. */
>+ int ppc_dmr0_regnum = 0;
It seems odd to have *both* a have_ flag and a regnum.
Usually, where we have regnum field, all tests are written
as "if (tdep->ppc_dmr0_regnum != -1)" instead.
>+ /* Check whether the kernel supports Dense Math registers. Native
>+ GDB accesses DMR through the dedicated PTRACE_GETDMREGS
request. */
>+ {
>+ gdb_byte buf[PPC_LINUX_SIZEOF_DMRREGSET];
>+ if (ptrace (PTRACE_GETDMREGS, tid, 0, buf) >= 0)
>+ features.has_dmr = true;
>+ }
Why this mix of new PTRACE_ and regsets?
Bye,
Ulrich
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v1] PowerPC: Add support for Dense Math registers (RFC02653)
2026-09-25 12:05 ` Ulrich Weigand
@ 2026-09-26 9:34 ` Abhay Kandpal
2026-09-28 9:22 ` Ulrich Weigand
0 siblings, 1 reply; 4+ messages in thread
From: Abhay Kandpal @ 2026-09-26 9:34 UTC (permalink / raw)
To: Ulrich Weigand, gdb-patches; +Cc: cel, Abhay Kandpal
[-- Attachment #1: Type: text/plain, Size: 5779 bytes --]
Hi Ulrich,
Thanks very much for the review. Responses below.
On 25/09/26 17:35, Ulrich Weigand wrote:
> Abhay Kandpal<abhay@linux.ibm.com> wrote:
>
>> A new target description (powerpc-dmr-vsx32l/64l) is introduced for
>> systems where DMR registers are available. The existing isa207 target
>> description is left unchanged so that systems without DMR support are
>> not affected. DMR availability is detected at runtime by probing the
>> kernel with PTRACE_GETDMREGS. On kernels without DMR support the
>> registers are gracefully skipped and show as unavailable.
> This looks good in general. One question about naming: most recent
> features have names that identify the base Power ISA level (isa205,
> isa207, etc.). Should we follow this precedent for the new target
> description name?
The existing names encode the base ISA level, but DMR is a later ISA
feature layered on an isa207-derived description, so|isa207-dmr| would
misstate the ISA level. A few options:
|1. powerpc-isa207-dmr-vsx64l| - names the base feature set the description extends
|2. powerpc-isa32-dmr-vsx64l| - names DMR's own ISA level (ISA 3.2)
|3. powerpc-dmr-vsx64l| - as posted, no ISA level
>
> A few other comments below.
>
>
>> if (features.wordsize == 8)
>> {
>> + /* HTM was disabled on POWER9 and later hardware following the
>> + transactional-memory erratum, so it does not coexist with the
>> + Dense Math facility introduced on later processors. The htm
>> + and has_dmr cases below are therefore mutually exclusive in
>> + practice. */
>> if (features.vsx)
>> tdesc = (features.htm ? tdesc_powerpc_isa207_htm_vsx64l
>> + : features.has_dmr ? tdesc_powerpc_dmr_vsx64l
> Even so, it would be preferable to add the newest feature first.
Will do. The comment then becomes unnecessary.
>
>
>> @@ -58,6 +59,7 @@ struct ppc_linux_features
>> bool ppr_dscr;
>> bool isa207;
>> bool htm;
>> + bool has_dmr;
> For this struct, precedent is not to use the "has_" prefix.
Will rename to dmr.
>
>
>> + <!-- Define one 1024-bit vector composed of eight 128-bit lanes -->
>> + <vector id="uint1024" type="uint128" count="8"/>
> "uint1024" is a surprising name for a vector type. I would have
> expected something like "v8uint128" ?
Agreed. I'll rename it and regenerate the description files.
>
>
>> @@ -159,6 +159,11 @@
>> #define NT_PPC_TM_CDSCR 0x10f
>> #endif
>>
>> +#ifndef PTRACE_GETDMREGS
>> +#define PTRACE_GETDMREGS 0x1f
>> +#define PTRACE_SETDMREGS 0x20
>> +#endif
> Please move this block higher up, together with the
> other PTRACE_ defines in this file.
>
> That said, it would have been preferable to use the
> regset mechanism like for all other recently added
> registers, rather than a completely new PTRACE_ call.
> I see in the gdbserver you actually do that! So please
> use the same method in gdb itself as well.
The dedicated calls were used on the native side because
that is what the kernel team pointed tooling at for DMR,
but I agree the inconsistency between gdb and gdbserver
isn't justified. In the kernel,|PTRACE_GETDMREGS| is a thin
wrapper around|copy_regset_to_user()| on the same regset that
|NT_PPC_DMR| reaches, and I've confirmed|PTRACE_GETREGSET| with
|NT_PPC_DMR| works on the enabled kernel.
So in v2 I'll convert the native side to the regset mechanism
throughout:|fetch_regset|/|store_regset| with|NT_PPC_DMR| in
|fetch_register|,|fetch_ppc_registers|,|store_register| and
|store_ppc_registers|, and a regset-based availability check in
|read_description|. That removes the need for the|PTRACE_GETDMREGS|/|PTRACE_SETDMREGS| defines, so I'll drop the
block rather than move it - unless something still needs them,
in which case I'll relocate it as you suggest.
>
>
>> + /* Check whether the kernel supports Dense Math registers. Native
>> + GDB accesses DMR through the dedicated PTRACE_GETDMREGS
> request. */
>> + {
>> + gdb_byte buf[PPC_LINUX_SIZEOF_DMRREGSET];
>> + if (ptrace (PTRACE_GETDMREGS, tid, 0, buf) >= 0)
>> + features.has_dmr = true;
>> + }
> Again it would be preferable to use a regset check instead.
>
> Is there a HWCAP bit we should check in addition, to indicate that
> the kernel and hypervisor support context-swapping these registers?
Yes -|PPC_FEATURE2_DMF| (0x00008000, Dense Math Facility). I'll add that
check. The kernel does save and restore these registers across context
switches. The hwcap bit and the DMR ptrace support are currently in
separate kernel branches here, so I'm assembling a tree with both before
validating v2.
>
>
>> + /* Dense Math registers. */
>> + int have_dmr = 0;
>> + /* Register number of dmr0, or -1 if DMR is not available. Set
>> + from PPC_DMR0_REGNUM when the target provides the dmr feature.
>> + Provided for register-offset computations (e.g. core file and
>> + pseudo-register handling) added in follow-up DMR work. */
>> + int ppc_dmr0_regnum = 0;
> It seems odd to have *both* a have_ flag and a regnum.
> Usually, where we have regnum field, all tests are written
> as "if (tdep->ppc_dmr0_regnum != -1)" instead.
Agreed. I'll drop|have_dmr| and test|tdep->ppc_dmr0_regnum != -1| instead.
>
>
>> + /* Check whether the kernel supports Dense Math registers. Native
>> + GDB accesses DMR through the dedicated PTRACE_GETDMREGS
> request. */
>> + {
>> + gdb_byte buf[PPC_LINUX_SIZEOF_DMRREGSET];
>> + if (ptrace (PTRACE_GETDMREGS, tid, 0, buf) >= 0)
>> + features.has_dmr = true;
>> + }
> Why this mix of new PTRACE_ and regsets?
Covered above - I'll move the native side to regsets so there's no mix.
Regards,
Abhay
>
>
> Bye,
> Ulrich
[-- Attachment #2: Type: text/html, Size: 9508 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v1] PowerPC: Add support for Dense Math registers (RFC02653)
2026-09-26 9:34 ` Abhay Kandpal
@ 2026-09-28 9:22 ` Ulrich Weigand
0 siblings, 0 replies; 4+ messages in thread
From: Ulrich Weigand @ 2026-09-28 9:22 UTC (permalink / raw)
To: Abhay Kandpal, gdb-patches; +Cc: cel, Abhay Kandpal
Abhay Kandpal <abhay@linux.ibm.com> wrote:
>The existing names encode the base ISA level, but DMR is a later ISA
>feature layered on an isa207-derived description, so isa207-dmr would
>misstate the ISA level. A few options:
>
>1. powerpc-isa207-dmr-vsx64l - names the base feature set the description extends
>2. powerpc-isa32-dmr-vsx64l - names DMR's own ISA level (ISA 3.2)
>3. powerpc-dmr-vsx64l - as posted, no ISA level
I'm not familiar with ISA 3.2 - is DMR mandatory or optional in 3.2?
And are there any *other* 3.2 features that GDB needs to implement?
I'd prefer "powerpc-isa32-vsx64l" to refer to an implementation of
all mandatory features (including DMR if mandatory), and if DMR is
optional, then in addition "powerpc-isa32-dmr-vsx64l" for the
combination of mandatory ISA 3.2 features plus DMR.
>So in v2 I'll convert the native side to the regset mechanism
>throughout: fetch_regset/store_regset with NT_PPC_DMR in
>fetch_register, fetch_ppc_registers, store_register and
>store_ppc_registers, and a regset-based availability check in
>read_description. That removes the need for the
>PTRACE_GETDMREGS/PTRACE_SETDMREGS defines, so I'll drop the
>block rather than move it - unless something still needs them,
>in which case I'll relocate it as you suggest.
No, if they're not needed, it's better to drop these defines.
>Yes - PPC_FEATURE2_DMF (0x00008000, Dense Math Facility). I'll add
that
>check. The kernel does save and restore these registers across context
>switches. The hwcap bit and the DMR ptrace support are currently in
>separate kernel branches here, so I'm assembling a tree with both before
>validating v2.
Thanks!
Bye,
Ulrich
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-28 9:23 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-24 6:30 [PATCH v1] PowerPC: Add support for Dense Math registers (RFC02653) Abhay Kandpal
2026-09-25 12:05 ` Ulrich Weigand
2026-09-26 9:34 ` Abhay Kandpal
2026-09-28 9:22 ` Ulrich Weigand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox