diff options
author | Alan Modra <amodra@bigpond.net.au> | 2007-08-30 13:13:59 +0000 |
---|---|---|
committer | Alan Modra <amodra@bigpond.net.au> | 2007-08-30 13:13:59 +0000 |
commit | 2dc5e5bea52f2ffe54966b2cb1e0bc5c872ec411 (patch) | |
tree | 3fda4aef8d286af9a50dc8054efbf2c9fd5bf69e /gdb/rs6000-tdep.c | |
parent | 4f7ad0a36938559637d48a61ba1970c914880bed (diff) | |
download | gdb-2dc5e5bea52f2ffe54966b2cb1e0bc5c872ec411.tar.gz |
* 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.
Diffstat (limited to 'gdb/rs6000-tdep.c')
-rw-r--r-- | gdb/rs6000-tdep.c | 273 |
1 files changed, 187 insertions, 86 deletions
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index f6afac9134e..352843471c7 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -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, ®size); + 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, ®size); + 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); } |