aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/linux-ppc-low.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2007-10-15 19:58:17 +0000
committerDaniel Jacobowitz <drow@false.org>2007-10-15 19:58:17 +0000
commit30ed0a8f0b4557aeb8bbbeee1bb1904bc45f747e (patch)
treed3b93b11841ac4a7c2290eed5ce5b92964790369 /gdb/gdbserver/linux-ppc-low.c
parent310a98e10257728271c1d3b817f7bfeb5c3cb88f (diff)
downloadgdb-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.c114
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, &regset[i * 16]);
+
+ collect_register_by_name ("vscr", &regset[32 * 16 + 12]);
+ collect_register_by_name ("vrsave", &regset[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, &regset[i * 16]);
+
+ supply_register_by_name ("vscr", &regset[32 * 16 + 12]);
+ supply_register_by_name ("vrsave", &regset[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, &regset->evr[i]);
+
+ collect_register_by_name ("acc", &regset->acc);
+ collect_register_by_name ("spefscr", &regset->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, &regset->evr[i]);
+
+ supply_register_by_name ("acc", &regset->acc);
+ supply_register_by_name ("spefscr", &regset->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 }
};