diff options
author | Carlos Eduardo Seo <cseo@linux.vnet.ibm.com> | 2007-10-29 20:26:42 +0000 |
---|---|---|
committer | Carlos Eduardo Seo <cseo@linux.vnet.ibm.com> | 2007-10-29 20:26:42 +0000 |
commit | 06caf7d297df7c596ca98678c1569e031f7c893e (patch) | |
tree | 0243affea7391be743c5fed9d236691a01235476 /gdb/rs6000-tdep.c | |
parent | 566221476275c4fdb5c0a32fbda95a7ce1f05f3b (diff) | |
download | gdb-06caf7d297df7c596ca98678c1569e031f7c893e.zip gdb-06caf7d297df7c596ca98678c1569e031f7c893e.tar.gz gdb-06caf7d297df7c596ca98678c1569e031f7c893e.tar.bz2 |
* 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.
Diffstat (limited to 'gdb/rs6000-tdep.c')
-rw-r--r-- | gdb/rs6000-tdep.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 55f2ee0..f133b78 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -194,6 +194,16 @@ ppc_floating_point_unit_p (struct gdbarch *gdbarch) && 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); +} /* Check that TABLE[GDB_REGNO] is not already initialized, and then set it to SIM_REGNO. @@ -436,6 +446,24 @@ 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. */ @@ -518,6 +546,50 @@ ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache, 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 + ppc_supply_reg (regcache, regnum, + 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 @@ -603,6 +675,52 @@ ppc_collect_fpregset (const struct regset *regset, 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 + ppc_collect_reg (regcache, regnum, + vrregs, offset, 4); +} /* Read a LEN-byte address from debugged memory address MEMADDR. */ |