diff options
author | Daniel Jacobowitz <drow@false.org> | 2007-10-15 19:58:17 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2007-10-15 19:58:17 +0000 |
commit | 30ed0a8f0b4557aeb8bbbeee1bb1904bc45f747e (patch) | |
tree | d3b93b11841ac4a7c2290eed5ce5b92964790369 /gdb/gdbserver/linux-ppc-low.c | |
parent | 310a98e10257728271c1d3b817f7bfeb5c3cb88f (diff) | |
download | gdb-30ed0a8f0b4557aeb8bbbeee1bb1904bc45f747e.zip gdb-30ed0a8f0b4557aeb8bbbeee1bb1904bc45f747e.tar.gz gdb-30ed0a8f0b4557aeb8bbbeee1bb1904bc45f747e.tar.bz2 |
* Makefile.in (clean): Remove new files.
(powerpc-32.o, powerpc-32.c, powerpc-e500.o, powerpc-e500.c)
(powerpc-64.o, powerpc-64.c): New rules.
* configure.srv: Use alternate register sets for powerpc64-*-linux*
with AltiVec, powerpc-*-linux* with AltiVec, and powerpc-*-linux*
with SPE.
* linux-ppc-low.c (ppc_regmap): Do not fetch the FP registers for
SPE targets.
(ppc_cannot_store_register): Do not check for FPSCR for SPE targets.
(PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS, ppc_fill_vrregset)
(ppc_store_vrregset, PTRACE_GETEVRREGS, PTRACE_SETEVRREGS)
(struct gdb_evrregset_t, ppc_fill_evrregset, ppc_store_evrregset): New.
(target_regsets): Add AltiVec and SPE register sets.
* configure.ac: Check for AltiVec and SPE.
* linux-ppc64-low.c (PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS)
(ppc_fill_vrregset, ppc_store_vrregset): New.
(target_regsets): Add AltiVec register set.
* configure: Regenerated.
* features/Makefile (WHICH): Add PowerPC register definitions.
(rs6000/powerpc-32-expedite, rs6000/powerpc-e500-expedite)
(rs6000/powerpc-64-expedite): New macros.
($(outdir)/%.dat): Handle subdirectories.
* regformats/rs6000/powerpc-32.dat, regformats/rs6000/powerpc-64.dat,
regformats/rs6000/powerpc-e500.dat: New generated files.
Diffstat (limited to 'gdb/gdbserver/linux-ppc-low.c')
-rw-r--r-- | gdb/gdbserver/linux-ppc-low.c | 114 |
1 files changed, 113 insertions, 1 deletions
diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c index ed8cdc1..14ee29b 100644 --- a/gdb/gdbserver/linux-ppc-low.c +++ b/gdb/gdbserver/linux-ppc-low.c @@ -35,6 +35,16 @@ static int ppc_regmap[] = PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4, PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4, PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4, +#ifdef __SPE__ + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, + -1, -1, -1, -1, +#else PT_FPR0*4, PT_FPR0*4 + 8, PT_FPR0*4+16, PT_FPR0*4+24, PT_FPR0*4+32, PT_FPR0*4+40, PT_FPR0*4+48, PT_FPR0*4+56, PT_FPR0*4+64, PT_FPR0*4+72, PT_FPR0*4+80, PT_FPR0*4+88, @@ -43,15 +53,23 @@ static int ppc_regmap[] = PT_FPR0*4+160, PT_FPR0*4+168, PT_FPR0*4+176, PT_FPR0*4+184, PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216, PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248, +#endif PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4, - PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4, }; +#ifdef __SPE__ + PT_CTR * 4, PT_XER * 4, -1 +#else + PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4 +#endif + }; static int ppc_cannot_store_register (int regno) { +#ifndef __SPE__ /* Some kernels do not allow us to store fpscr. */ if (regno == find_regno ("fpscr")) return 2; +#endif return 0; } @@ -113,7 +131,101 @@ static void ppc_fill_gregset (void *buf) collect_register (i, (char *) buf + ppc_regmap[i]); } +#ifdef __ALTIVEC__ + +#ifndef PTRACE_GETVRREGS +#define PTRACE_GETVRREGS 18 +#define PTRACE_SETVRREGS 19 +#endif + +#define SIZEOF_VRREGS 33*16+4 + +static void +ppc_fill_vrregset (void *buf) +{ + int i, base; + char *regset = buf; + + base = find_regno ("vr0"); + for (i = 0; i < 32; i++) + collect_register (base + i, ®set[i * 16]); + + collect_register_by_name ("vscr", ®set[32 * 16 + 12]); + collect_register_by_name ("vrsave", ®set[33 * 16]); +} + +static void +ppc_store_vrregset (const void *buf) +{ + int i, base; + const char *regset = buf; + + base = find_regno ("vr0"); + for (i = 0; i < 32; i++) + supply_register (base + i, ®set[i * 16]); + + supply_register_by_name ("vscr", ®set[32 * 16 + 12]); + supply_register_by_name ("vrsave", ®set[33 * 16]); +} + +#endif /* __ALTIVEC__ */ + +#ifdef __SPE__ + +#ifndef PTRACE_GETEVRREGS +#define PTRACE_GETEVRREGS 20 +#define PTRACE_SETEVRREGS 21 +#endif + +struct gdb_evrregset_t +{ + unsigned long evr[32]; + unsigned long long acc; + unsigned long spefscr; +}; + +static void +ppc_fill_evrregset (void *buf) +{ + int i, ev0; + struct gdb_evrregset_t *regset = buf; + + ev0 = find_regno ("ev0h"); + for (i = 0; i < 32; i++) + collect_register (ev0 + i, ®set->evr[i]); + + collect_register_by_name ("acc", ®set->acc); + collect_register_by_name ("spefscr", ®set->spefscr); +} + +static void +ppc_store_evrregset (const void *buf) +{ + int i, ev0; + const struct gdb_evrregset_t *regset = buf; + + ev0 = find_regno ("ev0h"); + for (i = 0; i < 32; i++) + supply_register (ev0 + i, ®set->evr[i]); + + supply_register_by_name ("acc", ®set->acc); + supply_register_by_name ("spefscr", ®set->spefscr); +} +#endif /* __SPE__ */ + struct regset_info target_regsets[] = { + /* List the extra register sets before GENERAL_REGS. That way we will + fetch them every time, but still fall back to PTRACE_PEEKUSER for the + general registers. Some kernels support these, but not the newer + PPC_PTRACE_GETREGS. */ +#ifdef __ALTIVEC__ + { PTRACE_GETVRREGS, PTRACE_SETVRREGS, SIZEOF_VRREGS, EXTENDED_REGS, + ppc_fill_vrregset, ppc_store_vrregset }, +#endif +#ifdef __SPE__ + { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 32 * 4 + 8 + 4, EXTENDED_REGS, + ppc_fill_evrregset, ppc_store_evrregset }, +#endif { 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL }, { 0, 0, -1, -1, NULL, NULL } }; |