Re: [patch] Add support for PPC Altivec registers in core files

Carlos Eduardo Seo
2007-10-23T19:20:46Z

[-- Attachment #1: Type: text/plain, Size: 631 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jim Blandy wrote:
>
> I can't approve this, but I can pick nits. :)
>
> The best place to explain why ppc32_linux_vrregset is necessary is in
> a comment above the definition in the code, not in the ChangeLog file.

Cleaned up the ChangeLog entry.

Thanks,

- --
Carlos Eduardo Seo
Software Engineer
IBM Linux Technology Center
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHHkl/qvq7Aov/qQARAkHtAJ4hOyyUiQ3Jt/48msaW9o2fh5EiuQCff4pC
GuwaTRGesBQxVYL4LEMhTCI=
=NWPD
-----END PGP SIGNATURE-----

[-- Attachment #2: altivec-core.diff --]
[-- Type: text/x-patch, Size: 9544 bytes --]

2007-10-22 Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>

* ppc-linux-tdep.c (ppc32_linux_reg_offsets): Corrected
swapped offsets and VRSAVE offset.
(ppc64_linux_reg_offsets): Corrected swapped offsets.
(ppc32_linux_vrregset): Added.
(ppc_linux_regset_from_core_section): Added support for
.reg-ppc-vmx section.
* ppc-tdep.h (ppc_altivec_support_p): Declare.
(ppc_supply_vrregset): Declare.
(ppc_collect_vrregset): Declare.
* rs6000-tdep.c (ppc_altivec_support_p): Added.
(ppc_supply_vrregset): Added.
(ppc_collect_vrregset): Added.
* corelow.c (get_core_registers): Added support for
.reg-ppc-vmx section.

Index: gdb/ppc-linux-tdep.c
===================================================================
--- gdb/ppc-linux-tdep.c.orig
+++ gdb/ppc-linux-tdep.c
@@ -650,8 +650,8 @@ static const struct ppc_reg_offsets ppc3

/* AltiVec registers. */
/* .vr0_offset = */ 0,
- /* .vrsave_offset = */ 512,
- /* .vscr_offset = */ 512 + 12
+ /* .vscr_offset = */ 512 + 12,
+ /* .vrsave_offset = */ 528
};

static const struct ppc_reg_offsets ppc64_linux_reg_offsets =
@@ -675,8 +675,8 @@ static const struct ppc_reg_offsets ppc6

/* AltiVec registers. */
/* .vr0_offset = */ 0,
- /* .vrsave_offset = */ 528,
- /* .vscr_offset = */ 512 + 12
+ /* .vscr_offset = */ 512 + 12,
+ /* .vrsave_offset = */ 528
};

static const struct regset ppc32_linux_gregset = {
@@ -700,6 +700,13 @@ static const struct regset ppc32_linux_f
NULL
};

+static const struct regset ppc32_linux_vrregset = {
+ &ppc32_linux_reg_offsets,
+ ppc_supply_vrregset,
+ ppc_collect_vrregset,
+ NULL
+};
+
const struct regset *
ppc_linux_gregset (int wordsize)
{
@@ -726,6 +733,8 @@ ppc_linux_regset_from_core_section (stru
}
if (strcmp (sect_name, ".reg2") == 0)
return &ppc32_linux_fpregset;
+ if (strcmp (sect_name, ".reg-ppc-vmx") == 0)
+ return &ppc32_linux_vrregset;
return NULL;
}

Index: gdb/ppc-tdep.h
===================================================================
--- gdb/ppc-tdep.h.orig
+++ gdb/ppc-tdep.h
@@ -73,6 +73,10 @@ int spe_register_p (int regno);
floating-point registers (f0 --- f31 and fpscr). */
int ppc_floating_point_unit_p (struct gdbarch *gdbarch);

+/* Return non-zero if the architecture described by GDBARCH has
+ Altivec registers (vr0 --- vr31, vrsave and vscr). */
+int ppc_altivec_support_p (struct gdbarch *gdbarch);
+
/* Register set description. */

struct ppc_reg_offsets
@@ -116,6 +120,14 @@ extern void ppc_supply_fpregset (const s
struct regcache *regcache,
int regnum, const void *fpregs, size_t len);

+/* Supply register REGNUM in the Altivec register set REGSET
+ from the buffer specified by VRREGS and LEN to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+extern void ppc_supply_vrregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *vrregs, size_t len);
+
/* Collect register REGNUM in the general-purpose register set
REGSET. from register cache REGCACHE into the buffer specified by
GREGS and LEN. If REGNUM is -1, do this for all registers in
@@ -134,6 +146,15 @@ extern void ppc_collect_fpregset (const
const struct regcache *regcache,
int regnum, void *fpregs, size_t len);

+/* Collect register REGNUM in the Altivec register set
+ REGSET from register cache REGCACHE into the buffer specified by
+ VRREGS and LEN. If REGNUM is -1, do this for all registers in
+ REGSET. */
+
+extern void ppc_collect_vrregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *vrregs, size_t len);
+
/* Private data that this module attaches to struct gdbarch. */

struct gdbarch_tdep
Index: gdb/rs6000-tdep.c
===================================================================
--- gdb/rs6000-tdep.c.orig
+++ gdb/rs6000-tdep.c
@@ -194,6 +194,17 @@ ppc_floating_point_unit_p (struct gdbarc
&& tdep->ppc_fpscr_regnum >= 0);
}

+/* Return non-zero if the architecture described by GDBARCH has
+ Altivec registers (vr0 --- vr31, vrsave and vscr). */
+int
+ppc_altivec_support_p (struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ return (tdep->ppc_vr0_regnum >= 0
+ && tdep->ppc_vrsave_regnum >= 0
+ && (tdep->ppc_vrsave_regnum - 1) >= 0);
+}

/* Check that TABLE[GDB_REGNO] is not already initialized, and then
set it to SIM_REGNO.
@@ -436,6 +447,24 @@ ppc_fpreg_offset (struct gdbarch_tdep *t
return -1;
}

+static int
+ppc_vrreg_offset (struct gdbarch_tdep *tdep,
+ const struct ppc_reg_offsets *offsets,
+ int regnum)
+{
+ if (regnum >= tdep->ppc_vr0_regnum
+ && regnum < tdep->ppc_vr0_regnum + ppc_num_vrs)
+ return offsets->vr0_offset + (regnum - tdep->ppc_vr0_regnum) * 8;
+
+ if (regnum == (tdep->ppc_vrsave_regnum - 1))
+ return offsets->vscr_offset;
+
+ if (regnum == tdep->ppc_vrsave_regnum)
+ return offsets->vrsave_offset;
+
+ return -1;
+}
+
/* Supply register REGNUM in the general-purpose register set REGSET
from the buffer specified by GREGS and LEN to register cache
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
@@ -518,6 +547,52 @@ ppc_supply_fpregset (const struct regset
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}

+/* Supply register REGNUM in the Altivec register set REGSET
+ from the buffer specified by VRREGS and LEN to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+void
+ppc_supply_vrregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *vrregs, size_t len)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep;
+ const struct ppc_reg_offsets *offsets;
+ size_t offset;
+
+ if (!ppc_altivec_support_p (gdbarch))
+ return;
+
+ tdep = gdbarch_tdep (gdbarch);
+ offsets = regset->descr;
+ if (regnum == -1)
+ {
+ int i;
+
+ for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset;
+ i < tdep->ppc_vr0_regnum + ppc_num_vrs;
+ i++, offset += 16)
+ ppc_supply_reg (regcache, i, vrregs, offset, 16);
+
+ ppc_supply_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
+ vrregs, offsets->vscr_offset, 4);
+
+ ppc_supply_reg (regcache, tdep->ppc_vrsave_regnum,
+ vrregs, offsets->vrsave_offset, 4);
+ return;
+ }
+
+ offset = ppc_vrreg_offset (tdep, offsets, regnum);
+ if ((regnum != tdep->ppc_vrsave_regnum) && (regnum != (tdep->ppc_vrsave_regnum - 1)))
+ ppc_supply_reg (regcache, regnum, vrregs, offset, 16);
+ else if (regnum == (tdep->ppc_vrsave_regnum - 1))
+ ppc_supply_reg (regcache, regnum,
+ vrregs, offsets->vscr_offset, 4);
+ else
+ ppc_supply_reg (regcache, regnum,
+ vrregs, offsets->vrsave_offset, 4);
+}
+
/* Collect register REGNUM in the general-purpose register set
REGSET from register cache REGCACHE into the buffer specified by
GREGS and LEN. If REGNUM is -1, do this for all registers in
@@ -603,6 +678,54 @@ ppc_collect_fpregset (const struct regse
ppc_collect_reg (regcache, regnum, fpregs, offset,
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}
+
+/* Collect register REGNUM in the Altivec register set
+ REGSET from register cache REGCACHE into the buffer specified by
+ VRREGS and LEN. If REGNUM is -1, do this for all registers in
+ REGSET. */
+
+void
+ppc_collect_vrregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *vrregs, size_t len)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep;
+ const struct ppc_reg_offsets *offsets;
+ size_t offset;
+
+ if (!ppc_altivec_support_p (gdbarch))
+ return;
+
+ tdep = gdbarch_tdep (gdbarch);
+ offsets = regset->descr;
+ if (regnum == -1)
+ {
+ int i;
+
+ for (i = tdep->ppc_vr0_regnum, offset = offsets->vr0_offset;
+ i < tdep->ppc_vr0_regnum + ppc_num_vrs;
+ i++, offset += 16)
+ ppc_collect_reg (regcache, i, vrregs, offset, 16);
+
+ ppc_collect_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
+ vrregs, offsets->vscr_offset, 4);
+
+ ppc_collect_reg (regcache, tdep->ppc_vrsave_regnum,
+ vrregs, offsets->vrsave_offset, 4);
+ return;
+ }
+
+ offset = ppc_vrreg_offset (tdep, offsets, regnum);
+ if ((regnum != tdep->ppc_vrsave_regnum) && (regnum != (tdep->ppc_vrsave_regnum - 1)))
+ ppc_collect_reg (regcache, regnum, vrregs, offset, 16);
+ else if (regnum == (tdep->ppc_vrsave_regnum - 1))
+ ppc_collect_reg (regcache, regnum,
+ vrregs, offsets->vscr_offset, 4);
+ else
+ ppc_collect_reg (regcache, regnum,
+ vrregs, offsets->vrsave_offset, 4);
+}
\f

/* Read a LEN-byte address from debugged memory address MEMADDR. */
Index: gdb/corelow.c
===================================================================
--- gdb/corelow.c.orig
+++ gdb/corelow.c
@@ -499,6 +499,8 @@ get_core_registers (struct regcache *reg
".reg2", 2, "floating-point", 0);
get_core_register_section (regcache,
".reg-xfp", 3, "extended floating-point", 0);
+ get_core_register_section (regcache,
+ ".reg-ppc-vmx", 3, "ppc Altivec", 0);

/* Supply dummy value for all registers not found in the core. */
for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)

[-- Attachment #3: altivec-core.diff.sig --]
[-- Type: application/octet-stream, Size: 65 bytes --]