* ppc-linux-nat.c (right_fill_reg): Delete.

(supply_gregset): Use ppc_supply_gregset.
	(supply_fpregset): Use ppc_supply_fpregset.
	(fill_gregset): Use ppc_collect_gregset.
	(fill_fpregset): Use ppc_collect_fpregset.
	* ppc-linux-tdep.c (PPC_LINUX_PT_*): Don't define.
	(right_supply_register, ppc_linux_supply_gregset): Delete.
	(ppc32_linux_supply_gregset, ppc64_linux_supply_gregset): Delete.
	(ppc_linux_supply_fpregset): Delete.
	(ppc_linux_collect_gregset): New function.
	(ppc32_linux_reg_offsets, ppc64_linux_reg_offsets): New.
	(ppc32_linux_gregset, ppc64_linux_gregset): Update to use reg offsets,
	ppc_linux_supply_gregset, and ppc_collect_gregset.
	(ppc_linux_fpregset): Rename to ppc32_linux_fpregset and update.
	(ppc_linux_gregset, ppc_linux_fpregset): New functions.
	(ppc_linux_regset_from_core_section): Update.
	* ppc-tdep.h (ppc_linux_gregset, ppc_linux_fpregset): Declare.
	(ppc_linux_supply_gregset, ppc_linux_supply_fpregset): Delete.
	(struct ppc_reg_offsets): Add gpr_size, xr_size, fpscr_size fields.
	* ppcobsd-tdep.c (ppcobsd_supply_gregset): Delete FIXME and assert.
	(ppcobsd_collect_gregset): Likewise.
	(_initialize_ppcnbsd_tdep): Init gpr_size, xr_size, fpscr_size.
	* ppcnbsd-tdep.c (_initialize_ppcobsd_tdep): Likewise.
	* ppcobsd-nat.c (_initialize_ppcobsd_nat): Likewise.
	* rs6000-aix-tdep.c (rs6000_aix32_reg_offsets): Likewise.
	(rs6000_aix64_reg_offsets): Likewise.
	(rs6000_aix_supply_regset): Call ppc_supply_fpregset without testing
	ppc_floating_point_unit_p.
	(rs6000_aix_collect_regset): Similarly.
	* rs6000-tdep.c (ppc_supply_reg): Add regsize param.  Adjust offset
	when regsize is larger than regcache register size.
	(ppc_collect_reg): Similarly zero pad when regsize is larger than
	regcache register size.
	(ppc_greg_offset): New function, split out from..
	(ppc_supply_gregset): ..here.  Separate code handling all regs from
	single reg case.  Correct xer offset.
	(ppc_fpreg_offset): New function, split out from..
	(ppc_supply_fpregset): ..here.  Separate code handling all regs from
	single reg case.
	(ppc_collect_gregset, ppc_collect_fpregset): Likewise.
	(ppc_supply_fpregset, ppc_collect_fpregset): Don't assert we have
	a fp unit, instead return if no fp.
This commit is contained in:
Alan Modra
2007-08-30 13:13:59 +00:00
parent 2db6cde736
commit f2db237aa1
9 changed files with 359 additions and 322 deletions

View File

@@ -302,22 +302,109 @@ rs6000_register_sim_regno (int reg)
/* Register set support functions. */
/* REGS + OFFSET contains register REGNUM in a field REGSIZE wide.
Write the register to REGCACHE. */
static void
ppc_supply_reg (struct regcache *regcache, int regnum,
const gdb_byte *regs, size_t offset)
const gdb_byte *regs, size_t offset, int regsize)
{
if (regnum != -1 && offset != -1)
regcache_raw_supply (regcache, regnum, regs + offset);
{
if (regsize > 4)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
int gdb_regsize = register_size (gdbarch, regnum);
if (gdb_regsize < regsize
&& gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
offset += regsize - gdb_regsize;
}
regcache_raw_supply (regcache, regnum, regs + offset);
}
}
/* Read register REGNUM from REGCACHE and store to REGS + OFFSET
in a field REGSIZE wide. Zero pad as necessary. */
static void
ppc_collect_reg (const struct regcache *regcache, int regnum,
gdb_byte *regs, size_t offset)
gdb_byte *regs, size_t offset, int regsize)
{
if (regnum != -1 && offset != -1)
regcache_raw_collect (regcache, regnum, regs + offset);
{
if (regsize > 4)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
int gdb_regsize = register_size (gdbarch, regnum);
if (gdb_regsize < regsize)
{
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
memset (regs + offset, 0, regsize - gdb_regsize);
offset += regsize - gdb_regsize;
}
else
memset (regs + offset + regsize - gdb_regsize, 0,
regsize - gdb_regsize);
}
}
regcache_raw_collect (regcache, regnum, regs + offset);
}
}
static int
ppc_greg_offset (struct gdbarch *gdbarch,
struct gdbarch_tdep *tdep,
const struct ppc_reg_offsets *offsets,
int regnum,
int *regsize)
{
*regsize = offsets->gpr_size;
if (regnum >= tdep->ppc_gp0_regnum
&& regnum < tdep->ppc_gp0_regnum + ppc_num_gprs)
return (offsets->r0_offset
+ (regnum - tdep->ppc_gp0_regnum) * offsets->gpr_size);
if (regnum == gdbarch_pc_regnum (gdbarch))
return offsets->pc_offset;
if (regnum == tdep->ppc_ps_regnum)
return offsets->ps_offset;
if (regnum == tdep->ppc_lr_regnum)
return offsets->lr_offset;
if (regnum == tdep->ppc_ctr_regnum)
return offsets->ctr_offset;
*regsize = offsets->xr_size;
if (regnum == tdep->ppc_cr_regnum)
return offsets->cr_offset;
if (regnum == tdep->ppc_xer_regnum)
return offsets->xer_offset;
if (regnum == tdep->ppc_mq_regnum)
return offsets->mq_offset;
return -1;
}
static int
ppc_fpreg_offset (struct gdbarch_tdep *tdep,
const struct ppc_reg_offsets *offsets,
int regnum)
{
if (regnum >= tdep->ppc_fp0_regnum
&& regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
return offsets->f0_offset + (regnum - tdep->ppc_fp0_regnum) * 8;
if (regnum == tdep->ppc_fpscr_regnum)
return offsets->fpscr_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. */
@@ -330,36 +417,37 @@ ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
const struct ppc_reg_offsets *offsets = regset->descr;
size_t offset;
int i;
int regsize;
for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
i++, offset += 4)
if (regnum == -1)
{
if (regnum == -1 || regnum == i)
ppc_supply_reg (regcache, i, gregs, offset);
int i;
int gpr_size = offsets->gpr_size;
for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
i++, offset += gpr_size)
ppc_supply_reg (regcache, i, gregs, offset, gpr_size);
ppc_supply_reg (regcache, gdbarch_pc_regnum (gdbarch),
gregs, offsets->pc_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_ps_regnum,
gregs, offsets->ps_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_lr_regnum,
gregs, offsets->lr_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_ctr_regnum,
gregs, offsets->ctr_offset, gpr_size);
ppc_supply_reg (regcache, tdep->ppc_cr_regnum,
gregs, offsets->cr_offset, offsets->xr_size);
ppc_supply_reg (regcache, tdep->ppc_xer_regnum,
gregs, offsets->xer_offset, offsets->xr_size);
ppc_supply_reg (regcache, tdep->ppc_mq_regnum,
gregs, offsets->mq_offset, offsets->xr_size);
return;
}
if (regnum == -1 || regnum == gdbarch_pc_regnum (current_gdbarch))
ppc_supply_reg (regcache, gdbarch_pc_regnum (current_gdbarch),
gregs, offsets->pc_offset);
if (regnum == -1 || regnum == tdep->ppc_ps_regnum)
ppc_supply_reg (regcache, tdep->ppc_ps_regnum,
gregs, offsets->ps_offset);
if (regnum == -1 || regnum == tdep->ppc_cr_regnum)
ppc_supply_reg (regcache, tdep->ppc_cr_regnum,
gregs, offsets->cr_offset);
if (regnum == -1 || regnum == tdep->ppc_lr_regnum)
ppc_supply_reg (regcache, tdep->ppc_lr_regnum,
gregs, offsets->lr_offset);
if (regnum == -1 || regnum == tdep->ppc_ctr_regnum)
ppc_supply_reg (regcache, tdep->ppc_ctr_regnum,
gregs, offsets->ctr_offset);
if (regnum == -1 || regnum == tdep->ppc_xer_regnum)
ppc_supply_reg (regcache, tdep->ppc_xer_regnum,
gregs, offsets->cr_offset);
if (regnum == -1 || regnum == tdep->ppc_mq_regnum)
ppc_supply_reg (regcache, tdep->ppc_mq_regnum, gregs, offsets->mq_offset);
offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, &regsize);
ppc_supply_reg (regcache, regnum, gregs, offset, regsize);
}
/* Supply register REGNUM in the floating-point register set REGSET
@@ -371,29 +459,36 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
int regnum, const void *fpregs, size_t len)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
const struct ppc_reg_offsets *offsets = regset->descr;
struct gdbarch_tdep *tdep;
const struct ppc_reg_offsets *offsets;
size_t offset;
int i;
gdb_assert (ppc_floating_point_unit_p (gdbarch));
if (!ppc_floating_point_unit_p (gdbarch))
return;
offset = offsets->f0_offset;
for (i = tdep->ppc_fp0_regnum;
i < tdep->ppc_fp0_regnum + ppc_num_fprs;
i++, offset += 8)
tdep = gdbarch_tdep (gdbarch);
offsets = regset->descr;
if (regnum == -1)
{
if (regnum == -1 || regnum == i)
ppc_supply_reg (regcache, i, fpregs, offset);
int i;
for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset;
i < tdep->ppc_fp0_regnum + ppc_num_fprs;
i++, offset += 8)
ppc_supply_reg (regcache, i, fpregs, offset, 8);
ppc_supply_reg (regcache, tdep->ppc_fpscr_regnum,
fpregs, offsets->fpscr_offset, offsets->fpscr_size);
return;
}
if (regnum == -1 || regnum == tdep->ppc_fpscr_regnum)
ppc_supply_reg (regcache, tdep->ppc_fpscr_regnum,
fpregs, offsets->fpscr_offset);
offset = ppc_fpreg_offset (tdep, offsets, regnum);
ppc_supply_reg (regcache, regnum, fpregs, offset,
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}
/* Collect register REGNUM in the general-purpose register set
REGSET. from register cache REGCACHE into the buffer specified by
REGSET from register cache REGCACHE into the buffer specified by
GREGS and LEN. If REGNUM is -1, do this for all registers in
REGSET. */
@@ -406,42 +501,41 @@ ppc_collect_gregset (const struct regset *regset,
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
const struct ppc_reg_offsets *offsets = regset->descr;
size_t offset;
int i;
int regsize;
offset = offsets->r0_offset;
for (i = tdep->ppc_gp0_regnum;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
i++, offset += 4)
if (regnum == -1)
{
if (regnum == -1 || regnum == i)
ppc_collect_reg (regcache, i, gregs, offset);
int i;
int gpr_size = offsets->gpr_size;
for (i = tdep->ppc_gp0_regnum, offset = offsets->r0_offset;
i < tdep->ppc_gp0_regnum + ppc_num_gprs;
i++, offset += gpr_size)
ppc_collect_reg (regcache, i, gregs, offset, gpr_size);
ppc_collect_reg (regcache, gdbarch_pc_regnum (gdbarch),
gregs, offsets->pc_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_ps_regnum,
gregs, offsets->ps_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_lr_regnum,
gregs, offsets->lr_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_ctr_regnum,
gregs, offsets->ctr_offset, gpr_size);
ppc_collect_reg (regcache, tdep->ppc_cr_regnum,
gregs, offsets->cr_offset, offsets->xr_size);
ppc_collect_reg (regcache, tdep->ppc_xer_regnum,
gregs, offsets->xer_offset, offsets->xr_size);
ppc_collect_reg (regcache, tdep->ppc_mq_regnum,
gregs, offsets->mq_offset, offsets->xr_size);
return;
}
if (regnum == -1 || regnum == gdbarch_pc_regnum (current_gdbarch))
ppc_collect_reg (regcache, gdbarch_pc_regnum (current_gdbarch),
gregs, offsets->pc_offset);
if (regnum == -1 || regnum == tdep->ppc_ps_regnum)
ppc_collect_reg (regcache, tdep->ppc_ps_regnum,
gregs, offsets->ps_offset);
if (regnum == -1 || regnum == tdep->ppc_cr_regnum)
ppc_collect_reg (regcache, tdep->ppc_cr_regnum,
gregs, offsets->cr_offset);
if (regnum == -1 || regnum == tdep->ppc_lr_regnum)
ppc_collect_reg (regcache, tdep->ppc_lr_regnum,
gregs, offsets->lr_offset);
if (regnum == -1 || regnum == tdep->ppc_ctr_regnum)
ppc_collect_reg (regcache, tdep->ppc_ctr_regnum,
gregs, offsets->ctr_offset);
if (regnum == -1 || regnum == tdep->ppc_xer_regnum)
ppc_collect_reg (regcache, tdep->ppc_xer_regnum,
gregs, offsets->xer_offset);
if (regnum == -1 || regnum == tdep->ppc_mq_regnum)
ppc_collect_reg (regcache, tdep->ppc_mq_regnum,
gregs, offsets->mq_offset);
offset = ppc_greg_offset (gdbarch, tdep, offsets, regnum, &regsize);
ppc_collect_reg (regcache, regnum, gregs, offset, regsize);
}
/* Collect register REGNUM in the floating-point register set
REGSET. from register cache REGCACHE into the buffer specified by
REGSET from register cache REGCACHE into the buffer specified by
FPREGS and LEN. If REGNUM is -1, do this for all registers in
REGSET. */
@@ -451,25 +545,32 @@ ppc_collect_fpregset (const struct regset *regset,
int regnum, void *fpregs, size_t len)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
const struct ppc_reg_offsets *offsets = regset->descr;
struct gdbarch_tdep *tdep;
const struct ppc_reg_offsets *offsets;
size_t offset;
int i;
gdb_assert (ppc_floating_point_unit_p (gdbarch));
if (!ppc_floating_point_unit_p (gdbarch))
return;
offset = offsets->f0_offset;
for (i = tdep->ppc_fp0_regnum;
i <= tdep->ppc_fp0_regnum + ppc_num_fprs;
i++, offset += 8)
tdep = gdbarch_tdep (gdbarch);
offsets = regset->descr;
if (regnum == -1)
{
if (regnum == -1 || regnum == i)
ppc_collect_reg (regcache, i, fpregs, offset);
int i;
for (i = tdep->ppc_fp0_regnum, offset = offsets->f0_offset;
i < tdep->ppc_fp0_regnum + ppc_num_fprs;
i++, offset += 8)
ppc_collect_reg (regcache, i, fpregs, offset, 8);
ppc_collect_reg (regcache, tdep->ppc_fpscr_regnum,
fpregs, offsets->fpscr_offset, offsets->fpscr_size);
return;
}
if (regnum == -1 || regnum == tdep->ppc_fpscr_regnum)
ppc_collect_reg (regcache, tdep->ppc_fpscr_regnum,
fpregs, offsets->fpscr_offset);
offset = ppc_fpreg_offset (tdep, offsets, regnum);
ppc_collect_reg (regcache, regnum, fpregs, offset,
regnum == tdep->ppc_fpscr_regnum ? offsets->fpscr_size : 8);
}