[PowerPC] Fix access to VSCR in linux targets

The 4-byte VSCR register is found inside a 16-byte field in the regset
returned by ptrace and in core files. The position of VSCR depends on
the endianess of the target, which was previously assumed to be
big-endian for the purpose of getting VSCR. This patch removes this
assumption to fix access to VSCR in little-endian mode.

gdb/ChangeLog:
2018-05-22  Pedro Franco de Carvalho  <pedromfc@linux.vnet.ibm.com>

	* ppc-tdep.h (struct ppc_reg_offsets): Remove vector register
	offset fields.
	* ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers
	for vector register offset fields.
	(ppc64_fbsd_reg_offsets): Likewise.
	* ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment
	to vector register offset fields.
	* ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment
	to vector register offset fields.
	* ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to
	vector register offset fields.
	* rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove
	initializers for vector register offset fields.
	(rs6000_aix64_reg_offsets): Likewise.
	* rs6000-tdep.c (ppc_vrreg_offset): Remove.
	(ppc_supply_vrregset): Remove.
	(ppc_collect_vrregset): Remove.
	* ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function.
	(ppc_linux_vrregset) : New function.
	(ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap)
	(ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals.
	(ppc32_linux_vrregset): Remove.
	(ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset
	and use result instead of ppc32_linux_vrregset.
	(ppc32_linux_reg_offsets): Remove initializers for vector register
	offset fields.
	(ppc64_linux_reg_offsets): Likewise.
	* ppc-linux-tdep.h (ppc_linux_vrregset): New declaration.
	* ppc-linux-nat.c: Include regset.h.
	(gdb_vrregset_t): Adjust comment to account for little-endian
	mode.
	(supply_vrregset, fill_vrregset): Remove.
	(fetch_altivec_register, store_altivec_register): Remove.
	(fetch_altivec_registers): Add regno parameter. Get regset using
	ppc_linux_vrregset. Use regset to supply registers.
	(store_altivec_registers): Add regno parameter. Get regset using
	ppc_linux_vrregset. Use regset to collect registers.
	(fetch_register): Call fetch_altivec_registers instead of
	fetch_altivec_register.
	(store_register): Call store_altivec_registers instead of
	store_altivec_register.
	(fetch_ppc_registers): Call fetch_altivec_registers with -1 for
	the new regno parameter.
	(store_ppc_registers): Call store_altivec_registers with -1 for
	the new regno parameter.

gdb/gdbserver/ChangeLog:
2018-05-22  Pedro Franco de Carvalho  <pedromfc@linux.vnet.ibm.com>

	* linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable.
	Set vscr_offset to 0 in little-endian mode and 12 in big-endian
	mode. Call collect_register_by_name with vscr using
	vscr_offset. Zero-pad vscr and vrsave fields in collector buffer.
	(ppc_store_vrregset): Add and set vscr_offset variable as in
	ppc_fill_vrregset. Call supply_register_by_name with vscr using
	vscr_offset.
This commit is contained in:
Pedro Franco de Carvalho 2018-05-22 11:09:05 -03:00
parent d078308a2e
commit 1d75a65809
13 changed files with 170 additions and 303 deletions

View File

@ -1,3 +1,51 @@
2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>
* ppc-tdep.h (struct ppc_reg_offsets): Remove vector register
offset fields.
* ppc-fbsd-tdep.c (ppc32_fbsd_reg_offsets): Remove initializers
for vector register offset fields.
(ppc64_fbsd_reg_offsets): Likewise.
* ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment
to vector register offset fields.
* ppc-obsd-tdep.c (_initialize_ppcnbsd_tdep): Remove assignment
to vector register offset fields.
* ppc-obsd-nat.c (_initialize_ppcobsd_nat): Remove assignment to
vector register offset fields.
* rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Remove
initializers for vector register offset fields.
(rs6000_aix64_reg_offsets): Likewise.
* rs6000-tdep.c (ppc_vrreg_offset): Remove.
(ppc_supply_vrregset): Remove.
(ppc_collect_vrregset): Remove.
* ppc-linux-tdep.c (ppc_linux_collect_vrregset): New function.
(ppc_linux_vrregset) : New function.
(ppc32_le_linux_vrregmap, ppc32_be_linux_vrregmap)
(ppc32_le_linux_vrregset, ppc32_be_linux_vrregset): New globals.
(ppc32_linux_vrregset): Remove.
(ppc_linux_iterate_over_regset_sections): Call ppc_linux_vrregset
and use result instead of ppc32_linux_vrregset.
(ppc32_linux_reg_offsets): Remove initializers for vector register
offset fields.
(ppc64_linux_reg_offsets): Likewise.
* ppc-linux-tdep.h (ppc_linux_vrregset): New declaration.
* ppc-linux-nat.c: Include regset.h.
(gdb_vrregset_t): Adjust comment to account for little-endian
mode.
(supply_vrregset, fill_vrregset): Remove.
(fetch_altivec_register, store_altivec_register): Remove.
(fetch_altivec_registers): Add regno parameter. Get regset using
ppc_linux_vrregset. Use regset to supply registers.
(store_altivec_registers): Add regno parameter. Get regset using
ppc_linux_vrregset. Use regset to collect registers.
(fetch_register): Call fetch_altivec_registers instead of
fetch_altivec_register.
(store_register): Call store_altivec_registers instead of
store_altivec_register.
(fetch_ppc_registers): Call fetch_altivec_registers with -1 for
the new regno parameter.
(store_ppc_registers): Call store_altivec_registers with -1 for
the new regno parameter.
2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>
* arch/ppc-linux-common.h (PPC_LINUX_SIZEOF_VRREGSET)

View File

@ -1,3 +1,13 @@
2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>
* linux-ppc-low.c (ppc_fill_vrregset): Add vscr_offset variable.
Set vscr_offset to 0 in little-endian mode and 12 in big-endian
mode. Call collect_register_by_name with vscr using
vscr_offset. Zero-pad vscr and vrsave fields in collector buffer.
(ppc_store_vrregset): Add and set vscr_offset variable as in
ppc_fill_vrregset. Call supply_register_by_name with vscr using
vscr_offset.
2018-05-22 Pedro Franco de Carvalho <pedromfc@linux.vnet.ibm.com>
* linux-ppc-low.c (SIZEOF_VSXREGS, SIZEOF_VRREGS): Remove.

View File

@ -486,12 +486,22 @@ ppc_fill_vrregset (struct regcache *regcache, void *buf)
{
int i, base;
char *regset = (char *) buf;
int vscr_offset = 0;
base = find_regno (regcache->tdesc, "vr0");
for (i = 0; i < 32; i++)
collect_register (regcache, base + i, &regset[i * 16]);
collect_register_by_name (regcache, "vscr", &regset[32 * 16 + 12]);
if (__BYTE_ORDER == __BIG_ENDIAN)
vscr_offset = 12;
/* Zero-pad the unused bytes in the fields for vscr and vrsave in
case they get displayed somewhere. */
memset (&regset[32 * 16], 0, 16);
collect_register_by_name (regcache, "vscr",
&regset[32 * 16 + vscr_offset]);
memset (&regset[33 * 16], 0, 16);
collect_register_by_name (regcache, "vrsave", &regset[33 * 16]);
}
@ -500,12 +510,17 @@ ppc_store_vrregset (struct regcache *regcache, const void *buf)
{
int i, base;
const char *regset = (const char *) buf;
int vscr_offset = 0;
base = find_regno (regcache->tdesc, "vr0");
for (i = 0; i < 32; i++)
supply_register (regcache, base + i, &regset[i * 16]);
supply_register_by_name (regcache, "vscr", &regset[32 * 16 + 12]);
if (__BYTE_ORDER == __BIG_ENDIAN)
vscr_offset = 12;
supply_register_by_name (regcache, "vscr",
&regset[32 * 16 + vscr_offset]);
supply_register_by_name (regcache, "vrsave", &regset[33 * 16]);
}

View File

@ -56,13 +56,7 @@ static const struct ppc_reg_offsets ppc32_fbsd_reg_offsets =
/* Floating-point registers. */
/* .f0_offset = */ 0,
/* .fpscr_offset = */ 256,
/* .fpscr_size = */ 8,
#ifdef NOTYET
/* AltiVec registers. */
/* .vr0_offset = */ 0,
/* .vscr_offset = */ 512 + 12,
/* .vrsave_offset = */ 512
#endif
/* .fpscr_size = */ 8
};
/* 64-bit regset descriptions. */
@ -84,13 +78,7 @@ static const struct ppc_reg_offsets ppc64_fbsd_reg_offsets =
/* Floating-point registers. */
/* .f0_offset = */ 0,
/* .fpscr_offset = */ 256,
/* .fpscr_size = */ 8,
#ifdef NOYET
/* AltiVec registers. */
/* .vr0_offset = */ 0,
/* .vscr_offset = */ 512 + 12,
/* .vrsave_offset = */ 528
#endif
/* .fpscr_size = */ 8
};
/* 32-bit general-purpose register set. */

View File

@ -24,6 +24,7 @@
#include "gdbthread.h"
#include "gdbcore.h"
#include "regcache.h"
#include "regset.h"
#include "target.h"
#include "linux-nat.h"
#include <sys/types.h>
@ -160,17 +161,18 @@ struct ppc_hw_breakpoint
Even though this vrsave register is not included in the regset
typedef, it is handled by the ptrace requests.
Note that GNU/Linux doesn't support little endian PPC hardware,
therefore the offset at which the real value of the VSCR register
is located will be always 12 bytes.
The layout is like this (where x is the actual value of the vscr reg): */
/* *INDENT-OFF* */
/*
Big-Endian:
|.|.|.|.|.....|.|.|.|.||.|.|.|x||.|
<-------> <-------><-------><->
VR0 VR31 VSCR VRSAVE
Little-Endian:
|.|.|.|.|.....|.|.|.|.||X|.|.|.||.|
<-------> <-------><-------><->
VR0 VR31 VSCR VRSAVE
*/
/* *INDENT-ON* */
@ -435,14 +437,13 @@ fetch_vsx_register (struct regcache *regcache, int tid, int regno)
registers set mechanism, as opposed to the interface for all the
other registers, that stores/fetches each register individually. */
static void
fetch_altivec_register (struct regcache *regcache, int tid, int regno)
fetch_altivec_registers (struct regcache *regcache, int tid,
int regno)
{
int ret;
int offset = 0;
gdb_vrregset_t regs;
struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
const struct regset *vrregset = ppc_linux_vrregset (gdbarch);
ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
if (ret < 0)
@ -452,19 +453,11 @@ fetch_altivec_register (struct regcache *regcache, int tid, int regno)
have_ptrace_getvrregs = 0;
return;
}
perror_with_name (_("Unable to fetch AltiVec register"));
perror_with_name (_("Unable to fetch AltiVec registers"));
}
/* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes
long on the hardware. We deal only with the lower 4 bytes of the
vector. VRSAVE is at the end of the array in a 4 bytes slot, so
there is no need to define an offset for it. */
if (regno == (tdep->ppc_vrsave_regnum - 1))
offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum);
regcache_raw_supply (regcache, regno,
regs + (regno
- tdep->ppc_vr0_regnum) * vrregsize + offset);
vrregset->supply_regset (vrregset, regcache, regno, &regs,
PPC_LINUX_SIZEOF_VRREGSET);
}
/* Fetch the top 32 bits of TID's general-purpose registers and the
@ -559,7 +552,7 @@ fetch_register (struct regcache *regcache, int tid, int regno)
register. */
if (have_ptrace_getvrregs)
{
fetch_altivec_register (regcache, tid, regno);
fetch_altivec_registers (regcache, tid, regno);
return;
}
/* If we have discovered that there is no ptrace support for
@ -646,31 +639,6 @@ supply_vsxregset (struct regcache *regcache, gdb_vsxregset_t *vsxregsetp)
}
}
static void
supply_vrregset (struct regcache *regcache, gdb_vrregset_t *vrregsetp)
{
int i;
struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
int offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum);
for (i = 0; i < num_of_vrregs; i++)
{
/* The last 2 registers of this set are only 32 bit long, not
128. However an offset is necessary only for VSCR because it
occupies a whole vector, while VRSAVE occupies a full 4 bytes
slot. */
if (i == (num_of_vrregs - 2))
regcache_raw_supply (regcache, tdep->ppc_vr0_regnum + i,
*vrregsetp + i * vrregsize + offset);
else
regcache_raw_supply (regcache, tdep->ppc_vr0_regnum + i,
*vrregsetp + i * vrregsize);
}
}
static void
fetch_vsx_registers (struct regcache *regcache, int tid)
{
@ -690,25 +658,6 @@ fetch_vsx_registers (struct regcache *regcache, int tid)
supply_vsxregset (regcache, &regs);
}
static void
fetch_altivec_registers (struct regcache *regcache, int tid)
{
int ret;
gdb_vrregset_t regs;
ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
if (ret < 0)
{
if (errno == EIO)
{
have_ptrace_getvrregs = 0;
return;
}
perror_with_name (_("Unable to fetch AltiVec registers"));
}
supply_vrregset (regcache, &regs);
}
/* This function actually issues the request to ptrace, telling
it to get all general-purpose registers and put them into the
specified regset.
@ -847,7 +796,7 @@ fetch_ppc_registers (struct regcache *regcache, int tid)
fetch_register (regcache, tid, tdep->ppc_fpscr_regnum);
if (have_ptrace_getvrregs)
if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
fetch_altivec_registers (regcache, tid);
fetch_altivec_registers (regcache, tid, -1);
if (have_ptrace_getsetvsxregs)
if (tdep->ppc_vsr0_upper_regnum != -1)
fetch_vsx_registers (regcache, tid);
@ -898,16 +847,14 @@ store_vsx_register (const struct regcache *regcache, int tid, int regno)
perror_with_name (_("Unable to store VSX register"));
}
/* Store one register. */
static void
store_altivec_register (const struct regcache *regcache, int tid, int regno)
store_altivec_registers (const struct regcache *regcache, int tid,
int regno)
{
int ret;
int offset = 0;
gdb_vrregset_t regs;
struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
const struct regset *vrregset = ppc_linux_vrregset (gdbarch);
ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
if (ret < 0)
@ -917,21 +864,15 @@ store_altivec_register (const struct regcache *regcache, int tid, int regno)
have_ptrace_getvrregs = 0;
return;
}
perror_with_name (_("Unable to fetch AltiVec register"));
perror_with_name (_("Unable to fetch AltiVec registers"));
}
/* VSCR is fetched as a 16 bytes quantity, but it is really 4 bytes
long on the hardware. */
if (regno == (tdep->ppc_vrsave_regnum - 1))
offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum);
regcache_raw_collect (regcache, regno,
regs + (regno
- tdep->ppc_vr0_regnum) * vrregsize + offset);
vrregset->collect_regset (vrregset, regcache, regno, &regs,
PPC_LINUX_SIZEOF_VRREGSET);
ret = ptrace (PTRACE_SETVRREGS, tid, 0, &regs);
if (ret < 0)
perror_with_name (_("Unable to store AltiVec register"));
perror_with_name (_("Unable to store AltiVec registers"));
}
/* Assuming TID referrs to an SPE process, set the top halves of TID's
@ -1034,7 +975,7 @@ store_register (const struct regcache *regcache, int tid, int regno)
if (altivec_register_p (gdbarch, regno))
{
store_altivec_register (regcache, tid, regno);
store_altivec_registers (regcache, tid, regno);
return;
}
if (vsx_register_p (gdbarch, regno))
@ -1110,29 +1051,6 @@ fill_vsxregset (const struct regcache *regcache, gdb_vsxregset_t *vsxregsetp)
*vsxregsetp + i * vsxregsize);
}
static void
fill_vrregset (const struct regcache *regcache, gdb_vrregset_t *vrregsetp)
{
int i;
struct gdbarch *gdbarch = regcache->arch ();
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
int offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum);
for (i = 0; i < num_of_vrregs; i++)
{
/* The last 2 registers of this set are only 32 bit long, not
128, but only VSCR is fetched as a 16 bytes quantity. */
if (i == (num_of_vrregs - 2))
regcache_raw_collect (regcache, tdep->ppc_vr0_regnum + i,
*vrregsetp + i * vrregsize + offset);
else
regcache_raw_collect (regcache, tdep->ppc_vr0_regnum + i,
*vrregsetp + i * vrregsize);
}
}
static void
store_vsx_registers (const struct regcache *regcache, int tid)
{
@ -1156,29 +1074,6 @@ store_vsx_registers (const struct regcache *regcache, int tid)
perror_with_name (_("Couldn't write VSX registers"));
}
static void
store_altivec_registers (const struct regcache *regcache, int tid)
{
int ret;
gdb_vrregset_t regs;
ret = ptrace (PTRACE_GETVRREGS, tid, 0, &regs);
if (ret < 0)
{
if (errno == EIO)
{
have_ptrace_getvrregs = 0;
return;
}
perror_with_name (_("Couldn't get AltiVec registers"));
}
fill_vrregset (regcache, &regs);
if (ptrace (PTRACE_SETVRREGS, tid, 0, &regs) < 0)
perror_with_name (_("Couldn't write AltiVec registers"));
}
/* This function actually issues the request to ptrace, telling
it to store all general-purpose registers present in the specified
regset.
@ -1337,7 +1232,7 @@ store_ppc_registers (const struct regcache *regcache, int tid)
}
if (have_ptrace_getvrregs)
if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
store_altivec_registers (regcache, tid);
store_altivec_registers (regcache, tid, -1);
if (have_ptrace_getsetvsxregs)
if (tdep->ppc_vsr0_upper_regnum != -1)
store_vsx_registers (regcache, tid);

View File

@ -444,6 +444,24 @@ ppc_linux_collect_gregset (const struct regset *regset,
}
}
static void
ppc_linux_collect_vrregset (const struct regset *regset,
const struct regcache *regcache,
int regnum, void *buf, size_t len)
{
gdb_byte *vrregs = (gdb_byte *) buf;
/* Zero-pad the unused bytes in the fields for vscr and vrsave
in case they get displayed somewhere (e.g. in core files). */
if (regnum == PPC_VSCR_REGNUM || regnum == -1)
memset (&vrregs[32 * 16], 0, 16);
if (regnum == PPC_VRSAVE_REGNUM || regnum == -1)
memset (&vrregs[33 * 16], 0, 16);
regcache_collect_regset (regset, regcache, regnum, buf, len);
}
/* Regset descriptions. */
static const struct ppc_reg_offsets ppc32_linux_reg_offsets =
{
@ -462,12 +480,7 @@ static const struct ppc_reg_offsets ppc32_linux_reg_offsets =
/* Floating-point registers. */
/* .f0_offset = */ 0,
/* .fpscr_offset = */ 256,
/* .fpscr_size = */ 8,
/* AltiVec registers. */
/* .vr0_offset = */ 0,
/* .vscr_offset = */ 512 + 12,
/* .vrsave_offset = */ 528
/* .fpscr_size = */ 8
};
static const struct ppc_reg_offsets ppc64_linux_reg_offsets =
@ -487,12 +500,7 @@ static const struct ppc_reg_offsets ppc64_linux_reg_offsets =
/* Floating-point registers. */
/* .f0_offset = */ 0,
/* .fpscr_offset = */ 256,
/* .fpscr_size = */ 8,
/* AltiVec registers. */
/* .vr0_offset = */ 0,
/* .vscr_offset = */ 512 + 12,
/* .vrsave_offset = */ 528
/* .fpscr_size = */ 8
};
static const struct regset ppc32_linux_gregset = {
@ -513,10 +521,36 @@ static const struct regset ppc32_linux_fpregset = {
ppc_collect_fpregset
};
static const struct regset ppc32_linux_vrregset = {
&ppc32_linux_reg_offsets,
ppc_supply_vrregset,
ppc_collect_vrregset
static const struct regcache_map_entry ppc32_le_linux_vrregmap[] =
{
{ 32, PPC_VR0_REGNUM, 16 },
{ 1, PPC_VSCR_REGNUM, 4 },
{ 1, REGCACHE_MAP_SKIP, 12 },
{ 1, PPC_VRSAVE_REGNUM, 4 },
{ 1, REGCACHE_MAP_SKIP, 12 },
{ 0 }
};
static const struct regcache_map_entry ppc32_be_linux_vrregmap[] =
{
{ 32, PPC_VR0_REGNUM, 16 },
{ 1, REGCACHE_MAP_SKIP, 12},
{ 1, PPC_VSCR_REGNUM, 4 },
{ 1, PPC_VRSAVE_REGNUM, 4 },
{ 1, REGCACHE_MAP_SKIP, 12 },
{ 0 }
};
static const struct regset ppc32_le_linux_vrregset = {
ppc32_le_linux_vrregmap,
regcache_supply_regset,
ppc_linux_collect_vrregset
};
static const struct regset ppc32_be_linux_vrregset = {
ppc32_be_linux_vrregmap,
regcache_supply_regset,
ppc_linux_collect_vrregset
};
static const struct regset ppc32_linux_vsxregset = {
@ -537,6 +571,15 @@ ppc_linux_fpregset (void)
return &ppc32_linux_fpregset;
}
const struct regset *
ppc_linux_vrregset (struct gdbarch *gdbarch)
{
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
return &ppc32_be_linux_vrregset;
else
return &ppc32_le_linux_vrregset;
}
/* Iterate over supported core file register note sections. */
static void
@ -557,8 +600,11 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
cb (".reg2", 264, &ppc32_linux_fpregset, NULL, cb_data);
if (have_altivec)
cb (".reg-ppc-vmx", PPC_LINUX_SIZEOF_VRREGSET, &ppc32_linux_vrregset,
"ppc Altivec", cb_data);
{
const struct regset *vrregset = ppc_linux_vrregset (gdbarch);
cb (".reg-ppc-vmx", PPC_LINUX_SIZEOF_VRREGSET, vrregset,
"ppc Altivec", cb_data);
}
if (have_vsx)
cb (".reg-ppc-vsx", PPC_LINUX_SIZEOF_VSXREGSET,

View File

@ -28,6 +28,9 @@ struct regset;
const struct regset *ppc_linux_gregset (int);
const struct regset *ppc_linux_fpregset (void);
/* Get the vector regset that matches the target byte order. */
const struct regset *ppc_linux_vrregset (struct gdbarch *gdbarch);
/* Extra register number constants. The Linux kernel stores a
"trap" code and the original value of r3 into special "registers";
these need to be saved and restored when performing an inferior

View File

@ -215,9 +215,5 @@ _initialize_ppcnbsd_tdep (void)
ppcnbsd_reg_offsets.fpscr_offset = 256;
ppcnbsd_reg_offsets.fpscr_size = 4;
/* AltiVec registers. */
ppcnbsd_reg_offsets.vr0_offset = 0;
ppcnbsd_reg_offsets.vrsave_offset = 512;
ppcnbsd_reg_offsets.vscr_offset = 524;
}
}

View File

@ -213,11 +213,6 @@ _initialize_ppcobsd_nat (void)
ppcobsd_fpreg_offsets.fpscr_size = 4;
#endif
/* AltiVec registers. */
ppcobsd_reg_offsets.vr0_offset = offsetof (struct vreg, vreg);
ppcobsd_reg_offsets.vscr_offset = offsetof (struct vreg, vscr);
ppcobsd_reg_offsets.vrsave_offset = offsetof (struct vreg, vrsave);
/* Support debugging kernel virtual memory images. */
bsd_kvm_add_target (ppcobsd_supply_pcb);
}

View File

@ -289,10 +289,6 @@ _initialize_ppcobsd_tdep (void)
ppcobsd_reg_offsets.f0_offset = 128;
ppcobsd_reg_offsets.fpscr_offset = -1;
/* AltiVec registers. */
ppcobsd_reg_offsets.vr0_offset = 0;
ppcobsd_reg_offsets.vscr_offset = 512;
ppcobsd_reg_offsets.vrsave_offset = 520;
}
if (ppcobsd_fpreg_offsets.fpscr_offset == 0)

View File

@ -100,11 +100,6 @@ struct ppc_reg_offsets
int f0_offset;
int fpscr_offset;
int fpscr_size;
/* AltiVec registers. */
int vr0_offset;
int vscr_offset;
int vrsave_offset;
};
extern void ppc_supply_reg (struct regcache *regcache, int regnum,

View File

@ -70,12 +70,7 @@ static struct ppc_reg_offsets rs6000_aix32_reg_offsets =
/* Floating-point registers. */
336, /* f0_offset */
56, /* fpscr_offset */
4, /* fpscr_size */
/* AltiVec registers. */
-1, /* vr0_offset */
-1, /* vscr_offset */
-1 /* vrsave_offset */
4 /* fpscr_size */
};
static struct ppc_reg_offsets rs6000_aix64_reg_offsets =
@ -95,12 +90,7 @@ static struct ppc_reg_offsets rs6000_aix64_reg_offsets =
/* Floating-point registers. */
312, /* f0_offset */
296, /* fpscr_offset */
4, /* fpscr_size */
/* AltiVec registers. */
-1, /* vr0_offset */
-1, /* vscr_offset */
-1 /* vrsave_offset */
4 /* fpscr_size */
};

View File

@ -485,24 +485,6 @@ ppc_fpreg_offset (struct gdbarch_tdep *tdep,
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) * 16;
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. */
@ -622,50 +604,6 @@ ppc_supply_vsxregset (const struct regset *regset, struct regcache *regcache,
ppc_supply_reg (regcache, regnum, (const gdb_byte *) vsxregs, 0, 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 = regcache->arch ();
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 = (const struct ppc_reg_offsets *) regset->regmap;
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, (const gdb_byte *) vrregs, offset, 16);
ppc_supply_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
(const gdb_byte *) vrregs, offsets->vscr_offset, 4);
ppc_supply_reg (regcache, tdep->ppc_vrsave_regnum,
(const gdb_byte *) 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, (const gdb_byte *) vrregs, offset, 16);
else
ppc_supply_reg (regcache, regnum,
(const gdb_byte *) vrregs, 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
@ -790,54 +728,6 @@ ppc_collect_vsxregset (const struct regset *regset,
ppc_collect_reg (regcache, regnum, (gdb_byte *) vsxregs, 0, 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 = regcache->arch ();
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 = (const struct ppc_reg_offsets *) regset->regmap;
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, (gdb_byte *) vrregs, offset, 16);
ppc_collect_reg (regcache, (tdep->ppc_vrsave_regnum - 1),
(gdb_byte *) vrregs, offsets->vscr_offset, 4);
ppc_collect_reg (regcache, tdep->ppc_vrsave_regnum,
(gdb_byte *) 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, (gdb_byte *) vrregs, offset, 16);
else
ppc_collect_reg (regcache, regnum,
(gdb_byte *) vrregs, offset, 4);
}
static int
insn_changes_sp_or_jumps (unsigned long insn)
{