Change the layout of the PowerPC E500 raw register cache to allow

the lower 32-bit halves of the GPRS to be their own raw registers,
not pseudoregisters.
* ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag;
add ppc_ev0_upper_regnum flag.
* rs6000-tdep.c: #include "reggroups.h".
(spe_register_p): Recognize the ev upper half registers as SPE
registers.
(init_sim_regno_table): Build gdb->sim mappings for the upper-half
registers.
(e500_move_ev_register): New function.
(e500_pseudo_register_read, e500_pseudo_register_write): The 'ev'
vector registers are the pseudo-registers now, formed by splicing
together the gprs and the upper-half registers.
(e500_register_reggroup_p): New function.
(P): Macro deleted.
(P8, A4): New macro.
(PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted.
(PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New
macros.
(registers_e500): Rearrange register set so that the raw register
set contains 32-bit GPRs and upper-half registers, and the SPE
vector registers become pseudo-registers.
(rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p;
it has been deleted.  Initialize ppc_ev0_upper_regnum.  Many other
register numbers are now the same for the E500 as they are for
other PowerPC variants.  Register e500_register_reggroup_p as the
register group function for the E500.
* Makefile.in (rs6000-tdep.o): Update dependencies.

Adapt PPC E500 native support to the new raw regcache layout.
* ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes.
(read_spliced_spe_reg, write_spliced_spe_reg): Deleted.
(fetch_spe_register, store_spe_register): Handle fetching/storing
all the SPE registers at once, if regno == -1.  These now take
over the job of fetch_spe_registers and store_spe_registers.
(fetch_spe_registers, store_spe_registers): Deleted.
(fetch_ppc_registers, store_ppc_registers): Fetch/store gprs
unconditionally; they're always raw.  Fetch/store SPE upper half
registers, if present, instead of ev registers.
(fetch_register, store_register): Remove sanity checks: gprs are
never pseudo-registers now, so we never need to even mention any
registers that are ever pseudoregisters.
This commit is contained in:
Jim Blandy 2004-08-04 17:17:55 +00:00
parent 9f64376872
commit 6ced10dd55
5 changed files with 286 additions and 334 deletions

View file

@ -1,5 +1,49 @@
2004-08-04 Jim Blandy <jimb@redhat.com>
Change the layout of the PowerPC E500 raw register cache to allow
the lower 32-bit halves of the GPRS to be their own raw registers,
not pseudoregisters.
* ppc-tdep.h (struct gdbarch_tdep): Remove ppc_gprs_pseudo_p flag;
add ppc_ev0_upper_regnum flag.
* rs6000-tdep.c: #include "reggroups.h".
(spe_register_p): Recognize the ev upper half registers as SPE
registers.
(init_sim_regno_table): Build gdb->sim mappings for the upper-half
registers.
(e500_move_ev_register): New function.
(e500_pseudo_register_read, e500_pseudo_register_write): The 'ev'
vector registers are the pseudo-registers now, formed by splicing
together the gprs and the upper-half registers.
(e500_register_reggroup_p): New function.
(P): Macro deleted.
(P8, A4): New macro.
(PPC_EV_REGS, PPC_GPRS_PSEUDO_REGS): Macros deleted.
(PPC_SPE_GP_REGS, PPC_SPE_UPPER_GP_REGS, PPC_EV_PSEUDO_REGS): New
macros.
(registers_e500): Rearrange register set so that the raw register
set contains 32-bit GPRs and upper-half registers, and the SPE
vector registers become pseudo-registers.
(rs6000_gdbarch_init): Don't initialize tdep->ppc_gprs_pseudo_p;
it has been deleted. Initialize ppc_ev0_upper_regnum. Many other
register numbers are now the same for the E500 as they are for
other PowerPC variants. Register e500_register_reggroup_p as the
register group function for the E500.
* Makefile.in (rs6000-tdep.o): Update dependencies.
Adapt PPC E500 native support to the new raw regcache layout.
* ppc-linux-nat.c (struct gdb_evrregset_t): Doc fixes.
(read_spliced_spe_reg, write_spliced_spe_reg): Deleted.
(fetch_spe_register, store_spe_register): Handle fetching/storing
all the SPE registers at once, if regno == -1. These now take
over the job of fetch_spe_registers and store_spe_registers.
(fetch_spe_registers, store_spe_registers): Deleted.
(fetch_ppc_registers, store_ppc_registers): Fetch/store gprs
unconditionally; they're always raw. Fetch/store SPE upper half
registers, if present, instead of ev registers.
(fetch_register, store_register): Remove sanity checks: gprs are
never pseudo-registers now, so we never need to even mention any
registers that are ever pseudoregisters.
Use a fixed register numbering when communicating with the PowerPC
simulator.
* ppc-tdep.h (struct gdbarch_tdep): New member: 'sim_regno'.

View file

@ -2402,7 +2402,7 @@ rs6000-tdep.o: rs6000-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
$(coff_xcoff_h) $(libxcoff_h) $(elf_bfd_h) $(solib_svr4_h) \
$(ppc_tdep_h) $(gdb_assert_h) $(dis_asm_h) $(trad_frame_h) \
$(frame_unwind_h) $(frame_base_h) $(infcall_h) $(sim_regno_h) \
$(gdb_sim_ppc_h)
$(gdb_sim_ppc_h) $(reggroups_h)
s390-nat.o: s390-nat.c $(defs_h) $(tm_h) $(regcache_h) $(inferior_h) \
$(s390_tdep_h)
s390-tdep.o: s390-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) $(inferior_h) \

View file

@ -123,12 +123,10 @@ typedef char gdb_vrregset_t[SIZEOF_VRREGS];
some SPE-specific registers.
GDB itself continues to claim the general-purpose registers are 32
bits long; the full 64-bit registers are called 'ev0' -- 'ev31'.
The ev registers are raw registers, and the GPR's are pseudo-
registers mapped onto their lower halves. This means that reading
and writing ev registers involves a mix of regset-at-once
PTRACE_{GET,SET}EVRREGS calls and register-at-a-time
PTRACE_{PEEK,POKE}USR calls.
bits long. It has unnamed raw registers that hold the upper halves
of the gprs, and the the full 64-bit SIMD views of the registers,
'ev0' -- 'ev31', are pseudo-registers that splice the top and
bottom halves together.
This is the structure filled in by PTRACE_GETEVRREGS and written to
the inferior's registers by PTRACE_SETEVRREGS. */
@ -283,105 +281,46 @@ get_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
memset (evrregset, 0, sizeof (*evrregset));
}
/* Assuming TID refers to an SPE process, store the full 64-bit value
of TID's ev register EV_REGNUM in DEST, getting the high bits from
EVRREGS and the low bits from the kernel via ptrace. */
static void
read_spliced_spe_reg (int tid, int ev_regnum,
struct gdb_evrregset_t *evrregs,
char *dest)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
/* Make sure we're trying to read an EV register; that's all we
handle. */
gdb_assert (tdep->ppc_ev0_regnum <= ev_regnum
&& ev_regnum <= tdep->ppc_ev31_regnum);
/* Make sure the sizes for the splicing add up. */
gdb_assert (sizeof (evrregs->evr[0]) + sizeof (PTRACE_XFER_TYPE)
== register_size (current_gdbarch, ev_regnum));
{
/* The index of ev_regnum in evrregs->evr[]. */
int ev_index = ev_regnum - tdep->ppc_ev0_regnum;
/* The number of the corresponding general-purpose register, which
holds the lower 32 bits of the EV register. */
int gpr_regnum = tdep->ppc_gp0_regnum + ev_index;
/* The offset of gpr_regnum in the process's uarea. */
CORE_ADDR gpr_uoffset = ppc_register_u_addr (gpr_regnum);
/* The low word of the EV register's value. */
PTRACE_XFER_TYPE low_word;
/* The PTRACE_PEEKUSR / PT_READ_U ptrace requests need to be able
to return arbitrary register values, so they can't return -1 to
indicate an error. So we clear errno, and then check it after
the call. */
errno = 0;
low_word = ptrace (PT_READ_U, tid, (PTRACE_ARG3_TYPE) gpr_uoffset, 0);
if (errno != 0)
{
char message[128];
sprintf (message, "reading register %s (#%d)",
REGISTER_NAME (ev_regnum), ev_regnum);
perror_with_name (message);
}
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
{
memcpy (dest, &evrregs->evr[ev_index],
sizeof (evrregs->evr[ev_index]));
* (PTRACE_XFER_TYPE *) (dest + sizeof (evrregs->evr[ev_index]))
= low_word;
}
else if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
{
* (PTRACE_XFER_TYPE *) dest = low_word;
memcpy (dest + sizeof (PTRACE_XFER_TYPE),
&evrregs->evr[ev_index], sizeof (evrregs->evr[ev_index]));
}
else
gdb_assert (0);
}
}
/* On SPE machines, supply the full value of the SPE register REGNO
from TID. This handles ev0 -- ev31 and acc, which are 64 bits
long, and spefscr, which is 32 bits long. */
/* Supply values from TID for SPE-specific raw registers: the upper
halves of the GPRs, the accumulator, and the spefscr. REGNO must
be the number of an upper half register, acc, spefscr, or -1 to
supply the values of all registers. */
static void
fetch_spe_register (int tid, int regno)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
struct gdb_evrregset_t evrregs;
gdb_assert (sizeof (evrregs.evr[0])
== register_size (current_gdbarch, tdep->ppc_ev0_upper_regnum));
gdb_assert (sizeof (evrregs.acc)
== register_size (current_gdbarch, tdep->ppc_acc_regnum));
gdb_assert (sizeof (evrregs.spefscr)
== register_size (current_gdbarch, tdep->ppc_spefscr_regnum));
get_spe_registers (tid, &evrregs);
if (tdep->ppc_ev0_regnum <= regno
&& regno <= tdep->ppc_ev31_regnum)
if (regno == -1)
{
char buf[MAX_REGISTER_SIZE];
read_spliced_spe_reg (tid, regno, &evrregs, buf);
regcache_raw_supply (current_regcache, regno, buf);
int i;
for (i = 0; i < ppc_num_gprs; i++)
regcache_raw_supply (current_regcache, tdep->ppc_ev0_upper_regnum + i,
&evrregs.evr[i]);
}
else if (regno == tdep->ppc_acc_regnum)
{
gdb_assert (sizeof (evrregs.acc)
== register_size (current_gdbarch, regno));
regcache_raw_supply (current_regcache, regno, &evrregs.acc);
}
else if (regno == tdep->ppc_spefscr_regnum)
{
gdb_assert (sizeof (evrregs.spefscr)
== register_size (current_gdbarch, regno));
regcache_raw_supply (current_regcache, regno, &evrregs.spefscr);
}
else
gdb_assert (0);
else if (tdep->ppc_ev0_upper_regnum <= regno
&& regno < tdep->ppc_ev0_upper_regnum + ppc_num_gprs)
regcache_raw_supply (current_regcache, regno,
&evrregs.evr[regno - tdep->ppc_ev0_upper_regnum]);
if (regno == -1
|| regno == tdep->ppc_acc_regnum)
regcache_raw_supply (current_regcache, tdep->ppc_acc_regnum, &evrregs.acc);
if (regno == -1
|| regno == tdep->ppc_spefscr_regnum)
regcache_raw_supply (current_regcache, tdep->ppc_spefscr_regnum,
&evrregs.spefscr);
}
static void
@ -394,12 +333,6 @@ fetch_register (int tid, int regno)
unsigned int offset; /* Offset of registers within the u area. */
char buf[MAX_REGISTER_SIZE];
/* Sanity check: this function should only be called to fetch raw
registers' values, never pseudoregisters' values. */
if (tdep->ppc_gp0_regnum <= regno
&& regno < tdep->ppc_gp0_regnum + ppc_num_gprs)
gdb_assert (! tdep->ppc_gprs_pseudo_p);
if (altivec_register_p (regno))
{
/* If this is the first time through, or if it is not the first
@ -512,42 +445,14 @@ fetch_altivec_registers (int tid)
supply_vrregset (&regs);
}
/* On SPE machines, fetch the full 64 bits of all the general-purpose
registers, as well as the SPE-specific registers 'acc' and
'spefscr'. */
static void
fetch_spe_registers (int tid)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
struct gdb_evrregset_t evrregs;
int i;
get_spe_registers (tid, &evrregs);
/* Splice and supply each of the EV registers. */
for (i = 0; i < ppc_num_gprs; i++)
{
char buf[MAX_REGISTER_SIZE];
read_spliced_spe_reg (tid, tdep->ppc_ev0_regnum + i, &evrregs, buf);
regcache_raw_supply (current_regcache, tdep->ppc_ev0_regnum + i, buf);
}
/* Supply the SPE-specific registers. */
regcache_raw_supply (current_regcache, tdep->ppc_acc_regnum, &evrregs.acc);
regcache_raw_supply (current_regcache, tdep->ppc_spefscr_regnum,
&evrregs.spefscr);
}
static void
fetch_ppc_registers (int tid)
{
int i;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (! tdep->ppc_gprs_pseudo_p)
for (i = 0; i < ppc_num_gprs; i++)
fetch_register (tid, tdep->ppc_gp0_regnum + i);
for (i = 0; i < ppc_num_gprs; i++)
fetch_register (tid, tdep->ppc_gp0_regnum + i);
if (tdep->ppc_fp0_regnum >= 0)
for (i = 0; i < ppc_num_fprs; i++)
fetch_register (tid, tdep->ppc_fp0_regnum + i);
@ -569,8 +474,8 @@ fetch_ppc_registers (int tid)
if (have_ptrace_getvrregs)
if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
fetch_altivec_registers (tid);
if (tdep->ppc_ev0_regnum >= 0)
fetch_spe_registers (tid);
if (tdep->ppc_ev0_upper_regnum >= 0)
fetch_spe_register (tid, -1);
}
/* Fetch registers from the child process. Fetch all registers if
@ -655,102 +560,58 @@ set_spe_registers (int tid, struct gdb_evrregset_t *evrregset)
}
}
/* Store the bytes at SRC as the contents of TID's EV register EV_REGNUM.
Write the less significant word to TID using ptrace, and copy the
more significant word to the appropriate slot in EVRREGS. */
static void
write_spliced_spe_reg (int tid, int ev_regnum,
struct gdb_evrregset_t *evrregs,
char *src)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
/* Make sure we're trying to write an EV register; that's all we
handle. */
gdb_assert (tdep->ppc_ev0_regnum <= ev_regnum
&& ev_regnum <= tdep->ppc_ev31_regnum);
/* Make sure the sizes for the splicing add up. */
gdb_assert (sizeof (evrregs->evr[0]) + sizeof (PTRACE_XFER_TYPE)
== register_size (current_gdbarch, ev_regnum));
{
int ev_index = ev_regnum - tdep->ppc_ev0_regnum;
/* The number of the corresponding general-purpose register, which
holds the lower 32 bits of the EV register. */
int gpr_regnum = tdep->ppc_gp0_regnum + ev_index;
/* The offset of gpr_regnum in the process's uarea. */
CORE_ADDR gpr_uoffset = ppc_register_u_addr (gpr_regnum);
/* The PTRACE_POKEUSR / PT_WRITE_U ptrace requests need to be able
to return arbitrary register values, so they can't return -1 to
indicate an error. So we clear errno, and check it again
afterwards. */
errno = 0;
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
{
memcpy (&evrregs->evr[ev_index], src, sizeof (evrregs->evr[ev_index]));
ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) gpr_uoffset,
* (PTRACE_XFER_TYPE *) (src + sizeof (evrregs->evr[0])));
}
else if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
{
ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) gpr_uoffset,
* (PTRACE_XFER_TYPE *) src);
memcpy (&evrregs->evr[ev_index], src + sizeof (PTRACE_XFER_TYPE),
sizeof (evrregs->evr[ev_index]));
}
else
gdb_assert (0);
if (errno != 0)
{
char message[128];
sprintf (message, "writing register %s (#%d)",
REGISTER_NAME (ev_regnum), ev_regnum);
perror_with_name (message);
}
}
}
/* Write GDB's value for the SPE register REGNO to TID. */
/* Write GDB's value for the SPE-specific raw register REGNO to TID.
If REGNO is -1, write the values of all the SPE-specific
registers. */
static void
store_spe_register (int tid, int regno)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
struct gdb_evrregset_t evrregs;
/* We can only read and write the entire EVR register set at a time,
so to write just a single register, we do a read-modify-write
maneuver. */
get_spe_registers (tid, &evrregs);
gdb_assert (sizeof (evrregs.evr[0])
== register_size (current_gdbarch, tdep->ppc_ev0_upper_regnum));
gdb_assert (sizeof (evrregs.acc)
== register_size (current_gdbarch, tdep->ppc_acc_regnum));
gdb_assert (sizeof (evrregs.spefscr)
== register_size (current_gdbarch, tdep->ppc_spefscr_regnum));
if (tdep->ppc_ev0_regnum >= 0
&& tdep->ppc_ev0_regnum <= regno && regno <= tdep->ppc_ev31_regnum)
{
char buf[MAX_REGISTER_SIZE];
regcache_raw_collect (current_regcache, regno, buf);
write_spliced_spe_reg (tid, regno, &evrregs, buf);
}
else if (tdep->ppc_acc_regnum >= 0
&& regno == tdep->ppc_acc_regnum)
{
gdb_assert (sizeof (evrregs.acc)
== register_size (current_gdbarch, regno));
regcache_raw_collect (current_regcache, regno, &evrregs.acc);
}
else if (tdep->ppc_spefscr_regnum >= 0
&& regno == tdep->ppc_spefscr_regnum)
{
gdb_assert (sizeof (evrregs.spefscr)
== register_size (current_gdbarch, regno));
regcache_raw_collect (current_regcache, regno, &evrregs.spefscr);
}
if (regno == -1)
/* Since we're going to write out every register, the code below
should store to every field of evrregs; if that doesn't happen,
make it obvious by initializing it with suspicious values. */
memset (&evrregs, 42, sizeof (evrregs));
else
gdb_assert (0);
/* We can only read and write the entire EVR register set at a
time, so to write just a single register, we do a
read-modify-write maneuver. */
get_spe_registers (tid, &evrregs);
if (regno == -1)
{
int i;
for (i = 0; i < ppc_num_gprs; i++)
regcache_raw_collect (current_regcache,
tdep->ppc_ev0_upper_regnum + i,
&evrregs.evr[i]);
}
else if (tdep->ppc_ev0_upper_regnum <= regno
&& regno < tdep->ppc_ev0_upper_regnum + ppc_num_gprs)
regcache_raw_collect (current_regcache, regno,
&evrregs.evr[regno - tdep->ppc_ev0_upper_regnum]);
if (regno == -1
|| regno == tdep->ppc_acc_regnum)
regcache_raw_collect (current_regcache,
tdep->ppc_acc_regnum,
&evrregs.acc);
if (regno == -1
|| regno == tdep->ppc_spefscr_regnum)
regcache_raw_collect (current_regcache,
tdep->ppc_spefscr_regnum,
&evrregs.spefscr);
/* Write back the modified register set. */
set_spe_registers (tid, &evrregs);
@ -766,12 +627,6 @@ store_register (int tid, int regno)
size_t bytes_to_transfer;
char buf[MAX_REGISTER_SIZE];
/* Sanity check: this function should only be called to store raw
registers' values, never pseudoregisters' values. */
if (tdep->ppc_gp0_regnum <= regno
&& regno < tdep->ppc_gp0_regnum + ppc_num_gprs)
gdb_assert (! tdep->ppc_gprs_pseudo_p);
if (altivec_register_p (regno))
{
store_altivec_register (tid, regno);
@ -874,45 +729,14 @@ store_altivec_registers (int tid)
perror_with_name ("Couldn't write AltiVec registers");
}
static void
store_spe_registers (int tid)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
struct gdb_evrregset_t evrregs;
int i;
/* The code below should store to every field of evrregs; if that
doesn't happen, make it obvious by initializing it with
suspicious values. */
memset (&evrregs, 42, sizeof (evrregs));
for (i = 0; i < ppc_num_gprs; i++)
{
char buf[MAX_REGISTER_SIZE];
regcache_raw_collect (current_regcache, tdep->ppc_ev0_regnum + i, buf);
write_spliced_spe_reg (tid, tdep->ppc_ev0_regnum + i, &evrregs, buf);
}
gdb_assert (sizeof (evrregs.acc)
== register_size (current_gdbarch, tdep->ppc_acc_regnum));
regcache_raw_collect (current_regcache, tdep->ppc_acc_regnum, &evrregs.acc);
gdb_assert (sizeof (evrregs.spefscr)
== register_size (current_gdbarch, tdep->ppc_spefscr_regnum));
regcache_raw_collect (current_regcache, tdep->ppc_acc_regnum, &evrregs.spefscr);
set_spe_registers (tid, &evrregs);
}
static void
store_ppc_registers (int tid)
{
int i;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (! tdep->ppc_gprs_pseudo_p)
for (i = 0; i < ppc_num_gprs; i++)
store_register (tid, tdep->ppc_gp0_regnum + i);
for (i = 0; i < ppc_num_gprs; i++)
store_register (tid, tdep->ppc_gp0_regnum + i);
if (tdep->ppc_fp0_regnum >= 0)
for (i = 0; i < ppc_num_fprs; i++)
store_register (tid, tdep->ppc_fp0_regnum + i);
@ -934,8 +758,8 @@ store_ppc_registers (int tid)
if (have_ptrace_getvrregs)
if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
store_altivec_registers (tid);
if (tdep->ppc_ev0_regnum >= 0)
store_spe_registers (tid);
if (tdep->ppc_ev0_upper_regnum >= 0)
store_spe_register (tid, -1);
}
void

View file

@ -144,7 +144,6 @@ struct gdbarch_tdep
int wordsize; /* size in bytes of fixed-point word */
const struct reg *regs; /* from current variant */
int ppc_gp0_regnum; /* GPR register 0 */
int ppc_gprs_pseudo_p; /* non-zero if GPRs are pseudo-registers */
int ppc_toc_regnum; /* TOC register */
int ppc_ps_regnum; /* Processor (or machine) status (%msr) */
int ppc_cr_regnum; /* Condition register */
@ -165,6 +164,7 @@ struct gdbarch_tdep
int ppc_mq_regnum; /* Multiply/Divide extension register */
int ppc_vr0_regnum; /* First AltiVec register */
int ppc_vrsave_regnum; /* Last AltiVec register */
int ppc_ev0_upper_regnum; /* First GPR upper half register */
int ppc_ev0_regnum; /* First ev register */
int ppc_ev31_regnum; /* Last ev register */
int ppc_acc_regnum; /* SPE 'acc' register */

View file

@ -39,6 +39,7 @@
#include "infcall.h"
#include "sim-regno.h"
#include "gdb/sim-ppc.h"
#include "reggroups.h"
#include "libbfd.h" /* for bfd_default_set_arch_mach */
#include "coff/internal.h" /* for libcoff.h */
@ -159,6 +160,12 @@ spe_register_p (int regno)
&& tdep->ppc_ev0_regnum <= regno && regno <= tdep->ppc_ev31_regnum)
return 1;
/* Is it a reference to one of the raw upper GPR halves? */
if (tdep->ppc_ev0_upper_regnum >= 0
&& tdep->ppc_ev0_upper_regnum <= regno
&& regno < tdep->ppc_ev0_upper_regnum + ppc_num_gprs)
return 1;
/* Is it a reference to the 64-bit accumulator, and do we have that? */
if (tdep->ppc_acc_regnum >= 0
&& tdep->ppc_acc_regnum == regno)
@ -254,6 +261,11 @@ init_sim_regno_table (struct gdbarch *arch)
set_sim_regno (sim_regno,
tdep->ppc_ev0_regnum + i,
sim_ppc_ev0_regnum + i);
if (tdep->ppc_ev0_upper_regnum >= 0)
for (i = 0; i < ppc_num_gprs; i++)
set_sim_regno (sim_regno,
tdep->ppc_ev0_upper_regnum + i,
sim_ppc_rh0_regnum + i);
if (tdep->ppc_acc_regnum >= 0)
set_sim_regno (sim_regno, tdep->ppc_acc_regnum, sim_ppc_acc_regnum);
/* spefscr is a special-purpose register, so the code below handles it. */
@ -1865,55 +1877,113 @@ rs6000_value_to_register (struct frame_info *frame,
put_frame_register (frame, regnum, to);
}
/* Move SPE vector register values between a 64-bit buffer and the two
32-bit raw register halves in a regcache. This function handles
both splitting a 64-bit value into two 32-bit halves, and joining
two halves into a whole 64-bit value, depending on the function
passed as the MOVE argument.
EV_REG must be the number of an SPE evN vector register --- a
pseudoregister. REGCACHE must be a regcache, and BUFFER must be a
64-bit buffer.
Call MOVE once for each 32-bit half of that register, passing
REGCACHE, the number of the raw register corresponding to that
half, and the address of the appropriate half of BUFFER.
For example, passing 'regcache_raw_read' as the MOVE function will
fill BUFFER with the full 64-bit contents of EV_REG. Or, passing
'regcache_raw_supply' will supply the contents of BUFFER to the
appropriate pair of raw registers in REGCACHE.
You may need to cast away some 'const' qualifiers when passing
MOVE, since this function can't tell at compile-time which of
REGCACHE or BUFFER is acting as the source of the data. If C had
co-variant type qualifiers, ... */
static void
e500_move_ev_register (void (*move) (struct regcache *regcache,
int regnum, void *buf),
struct regcache *regcache, int ev_reg,
void *buffer)
{
struct gdbarch *arch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
int reg_index;
char *byte_buffer = buffer;
gdb_assert (tdep->ppc_ev0_regnum <= ev_reg
&& ev_reg < tdep->ppc_ev0_regnum + ppc_num_gprs);
reg_index = ev_reg - tdep->ppc_ev0_regnum;
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
{
move (regcache, tdep->ppc_ev0_upper_regnum + reg_index, byte_buffer);
move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer + 4);
}
else
{
move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer);
move (regcache, tdep->ppc_ev0_upper_regnum + reg_index, byte_buffer + 4);
}
}
static void
e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, void *buffer)
{
int base_regnum;
int offset = 0;
char temp_buffer[MAX_REGISTER_SIZE];
struct gdbarch *regcache_arch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (reg_nr >= tdep->ppc_gp0_regnum
&& reg_nr < tdep->ppc_gp0_regnum + ppc_num_gprs)
{
base_regnum = reg_nr - tdep->ppc_gp0_regnum + tdep->ppc_ev0_regnum;
/* Build the value in the provided buffer. */
/* Read the raw register of which this one is the lower portion. */
regcache_raw_read (regcache, base_regnum, temp_buffer);
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
offset = 4;
memcpy ((char *) buffer, temp_buffer + offset, 4);
}
gdb_assert (regcache_arch == gdbarch);
if (tdep->ppc_ev0_regnum <= reg_nr
&& reg_nr < tdep->ppc_ev0_regnum + ppc_num_gprs)
e500_move_ev_register (regcache_raw_read, regcache, reg_nr, buffer);
else
/* We should only be called on pseudo-registers. */
gdb_assert (0);
}
static void
e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, const void *buffer)
{
int base_regnum;
int offset = 0;
char temp_buffer[MAX_REGISTER_SIZE];
struct gdbarch *regcache_arch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (reg_nr >= tdep->ppc_gp0_regnum
&& reg_nr < tdep->ppc_gp0_regnum + ppc_num_gprs)
{
base_regnum = reg_nr - tdep->ppc_gp0_regnum + tdep->ppc_ev0_regnum;
/* reg_nr is 32 bit here, and base_regnum is 64 bits. */
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
offset = 4;
gdb_assert (regcache_arch == gdbarch);
if (tdep->ppc_ev0_regnum <= reg_nr
&& reg_nr < tdep->ppc_ev0_regnum + ppc_num_gprs)
e500_move_ev_register ((void (*) (struct regcache *, int, void *))
regcache_raw_write,
regcache, reg_nr, (void *) buffer);
else
/* We should only be called on pseudo-registers. */
gdb_assert (0);
}
/* Let's read the value of the base register into a temporary
buffer, so that overwriting the last four bytes with the new
value of the pseudo will leave the upper 4 bytes unchanged. */
regcache_raw_read (regcache, base_regnum, temp_buffer);
/* The E500 needs a custom reggroup function: it has anonymous raw
registers, and default_register_reggroup_p assumes that anonymous
registers are not members of any reggroup. */
static int
e500_register_reggroup_p (struct gdbarch *gdbarch,
int regnum,
struct reggroup *group)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* Write as an 8 byte quantity. */
memcpy (temp_buffer + offset, (char *) buffer, 4);
regcache_raw_write (regcache, base_regnum, temp_buffer);
}
/* The save and restore register groups need to include the
upper-half registers, even though they're anonymous. */
if ((group == save_reggroup
|| group == restore_reggroup)
&& (tdep->ppc_ev0_upper_regnum <= regnum
&& regnum < tdep->ppc_ev0_upper_regnum + ppc_num_gprs))
return 1;
/* In all other regards, the default reggroup definition is fine. */
return default_register_reggroup_p (gdbarch, regnum, group);
}
/* Convert a DBX STABS register number to a GDB register number. */
@ -2176,8 +2246,9 @@ rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
/* Return a struct reg defining floating-point register NAME. */
#define F(name) { STR(name), 8, 8, 1, 0, -1 }
/* Return a struct reg defining a pseudo register NAME. */
#define P(name) { STR(name), 4, 8, 0, 1, -1 }
/* Return a struct reg defining a pseudo register NAME that is 64 bits
long on all systems. */
#define P8(name) { STR(name), 8, 8, 0, 1, -1 }
/* Return a struct reg defining register NAME that's 32 bits on 32-bit
systems and that doesn't exist on 64-bit systems. */
@ -2190,6 +2261,10 @@ rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
/* Return a struct reg placeholder for a register that doesn't exist. */
#define R0 { 0, 0, 0, 0, 0, -1 }
/* Return a struct reg defining an anonymous raw register that's 32
bits on all systems. */
#define A4 { 0, 4, 4, 0, 0, -1 }
/* Return a struct reg defining an SPR named NAME that is 32 bits on
32-bit systems and 64 bits on 64-bit systems. */
#define S(name) { STR(name), 4, 8, 0, 0, ppc_spr_ ## name }
@ -2254,19 +2329,38 @@ rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
/*143*/R16(vr24),R16(vr25),R16(vr26),R16(vr27),R16(vr28),R16(vr29),R16(vr30),R16(vr31), \
/*151*/R4(vscr), R4(vrsave)
/* Vectors of hi-lo general purpose registers. */
#define PPC_EV_REGS \
/* 0*/R8(ev0), R8(ev1), R8(ev2), R8(ev3), R8(ev4), R8(ev5), R8(ev6), R8(ev7), \
/* 8*/R8(ev8), R8(ev9), R8(ev10),R8(ev11),R8(ev12),R8(ev13),R8(ev14),R8(ev15), \
/*16*/R8(ev16),R8(ev17),R8(ev18),R8(ev19),R8(ev20),R8(ev21),R8(ev22),R8(ev23), \
/*24*/R8(ev24),R8(ev25),R8(ev26),R8(ev27),R8(ev28),R8(ev29),R8(ev30),R8(ev31)
/* Lower half of the EV registers. */
#define PPC_GPRS_PSEUDO_REGS \
/* 0 */ P(r0), P(r1), P(r2), P(r3), P(r4), P(r5), P(r6), P(r7), \
/* 8 */ P(r8), P(r9), P(r10),P(r11),P(r12),P(r13),P(r14),P(r15), \
/* 16 */ P(r16),P(r17),P(r18),P(r19),P(r20),P(r21),P(r22),P(r23), \
/* 24 */ P(r24),P(r25),P(r26),P(r27),P(r28),P(r29),P(r30),P(r31)
/* On machines supporting the SPE APU, the general-purpose registers
are 64 bits long. There are SIMD vector instructions to treat them
as pairs of floats, but the rest of the instruction set treats them
as 32-bit registers, and only operates on their lower halves.
In the GDB regcache, we treat their high and low halves as separate
registers. The low halves we present as the general-purpose
registers, and then we have pseudo-registers that stitch together
the upper and lower halves and present them as pseudo-registers. */
/* SPE GPR lower halves --- raw registers. */
#define PPC_SPE_GP_REGS \
/* 0 */ R4(r0), R4(r1), R4(r2), R4(r3), R4(r4), R4(r5), R4(r6), R4(r7), \
/* 8 */ R4(r8), R4(r9), R4(r10),R4(r11),R4(r12),R4(r13),R4(r14),R4(r15), \
/* 16 */ R4(r16),R4(r17),R4(r18),R4(r19),R4(r20),R4(r21),R4(r22),R4(r23), \
/* 24 */ R4(r24),R4(r25),R4(r26),R4(r27),R4(r28),R4(r29),R4(r30),R4(r31)
/* SPE GPR upper halves --- anonymous raw registers. */
#define PPC_SPE_UPPER_GP_REGS \
/* 0 */ A4, A4, A4, A4, A4, A4, A4, A4, \
/* 8 */ A4, A4, A4, A4, A4, A4, A4, A4, \
/* 16 */ A4, A4, A4, A4, A4, A4, A4, A4, \
/* 24 */ A4, A4, A4, A4, A4, A4, A4, A4
/* SPE GPR vector registers --- pseudo registers based on underlying
gprs and the anonymous upper half raw registers. */
#define PPC_EV_PSEUDO_REGS \
/* 0*/P8(ev0), P8(ev1), P8(ev2), P8(ev3), P8(ev4), P8(ev5), P8(ev6), P8(ev7), \
/* 8*/P8(ev8), P8(ev9), P8(ev10),P8(ev11),P8(ev12),P8(ev13),P8(ev14),P8(ev15),\
/*16*/P8(ev16),P8(ev17),P8(ev18),P8(ev19),P8(ev20),P8(ev21),P8(ev22),P8(ev23),\
/*24*/P8(ev24),P8(ev25),P8(ev26),P8(ev27),P8(ev28),P8(ev29),P8(ev30),P8(ev31)
/* IBM POWER (pre-PowerPC) architecture, user-level view. We only cover
user-level SPR's. */
@ -2446,16 +2540,14 @@ static const struct reg registers_7400[] =
/* Motorola e500. */
static const struct reg registers_e500[] =
{
R(pc), R(ps),
/* cr, lr, ctr, xer, "" */
PPC_UISA_NOFP_SPRS,
/* 7...38 */
PPC_EV_REGS,
R8(acc), S4(spefscr),
/* 0 .. 31 */ PPC_SPE_GP_REGS,
/* 32 .. 63 */ PPC_SPE_UPPER_GP_REGS,
/* 64 .. 65 */ R(pc), R(ps),
/* 66 .. 70 */ PPC_UISA_NOFP_SPRS,
/* 71 .. 72 */ R8(acc), S4(spefscr),
/* NOTE: Add new registers here the end of the raw register
list and just before the first pseudo register. */
/* 41...72 */
PPC_GPRS_PSEUDO_REGS
/* 73 .. 104 */ PPC_EV_PSEUDO_REGS
};
/* Information about a particular processor variant. */
@ -2987,7 +3079,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->regs = v->regs;
tdep->ppc_gp0_regnum = 0;
tdep->ppc_gprs_pseudo_p = 0;
tdep->ppc_toc_regnum = 2;
tdep->ppc_ps_regnum = 65;
tdep->ppc_cr_regnum = 66;
@ -3005,6 +3096,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->ppc_sr0_regnum = 71;
tdep->ppc_vr0_regnum = -1;
tdep->ppc_vrsave_regnum = -1;
tdep->ppc_ev0_upper_regnum = -1;
tdep->ppc_ev0_regnum = -1;
tdep->ppc_ev31_regnum = -1;
tdep->ppc_acc_regnum = -1;
@ -3047,26 +3139,18 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
tdep->ppc_vrsave_regnum = 152;
break;
case bfd_mach_ppc_e500:
tdep->ppc_gp0_regnum = 41;
tdep->ppc_gprs_pseudo_p = 1;
tdep->ppc_toc_regnum = -1;
tdep->ppc_ps_regnum = 1;
tdep->ppc_cr_regnum = 2;
tdep->ppc_lr_regnum = 3;
tdep->ppc_ctr_regnum = 4;
tdep->ppc_xer_regnum = 5;
tdep->ppc_ev0_regnum = 7;
tdep->ppc_ev31_regnum = 38;
tdep->ppc_ev0_upper_regnum = 32;
tdep->ppc_ev0_regnum = 73;
tdep->ppc_ev31_regnum = 104;
tdep->ppc_acc_regnum = 71;
tdep->ppc_spefscr_regnum = 72;
tdep->ppc_fp0_regnum = -1;
tdep->ppc_fpscr_regnum = -1;
tdep->ppc_sr0_regnum = -1;
tdep->ppc_acc_regnum = 39;
tdep->ppc_spefscr_regnum = 40;
set_gdbarch_pc_regnum (gdbarch, 0);
set_gdbarch_sp_regnum (gdbarch, tdep->ppc_gp0_regnum + 1);
set_gdbarch_deprecated_fp_regnum (gdbarch, tdep->ppc_gp0_regnum + 1);
set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write);
set_gdbarch_register_reggroup_p (gdbarch, e500_register_reggroup_p);
break;
case bfd_mach_ppc64: