aboutsummaryrefslogtreecommitdiff
path: root/gdb/rs6000-tdep.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2011-03-18 18:38:44 +0000
committerPedro Alves <palves@redhat.com>2011-03-18 18:38:44 +0000
commit05d1431c1e0a4ecf30462109f5fb9876d78b7b4a (patch)
tree76012c85051dd07166944e314a83502d47b1ba1a /gdb/rs6000-tdep.c
parent5548b4ce8ccff9f4a198fdfbcc47a83baa9ed876 (diff)
downloadgdb-05d1431c1e0a4ecf30462109f5fb9876d78b7b4a.zip
gdb-05d1431c1e0a4ecf30462109f5fb9876d78b7b4a.tar.gz
gdb-05d1431c1e0a4ecf30462109f5fb9876d78b7b4a.tar.bz2
gdb/
* regcache.h (regcache_raw_read, regcache_raw_read_signed) (regcache_raw_read_unsigned, regcache_raw_read_signed) (regcache_raw_read_unsigned, regcache_raw_read_part) (regcache_cooked_read, regcache_cooked_read_signed) (regcache_cooked_read_unsigned, regcache_cooked_read_part) (regcache_cooked_read_ftype): Change return to enum register_status. * regcache.c: Include exceptions.h (regcache_save): Adjust to handle REG_UNAVAILABLE registers. (do_cooked_read): Change return to enum register_status. Always forward to regcache_cooked_read. (regcache_raw_read): Change return to enum register_status. If the register is not REG_VALID, memset the buffer. Return the register's status. (regcache_raw_read_signed): Handle non-REG_VALID registers and return the register's status. (regcache_raw_read_unsigned): Ditto. (regcache_cooked_read): Change return to enum register_status. Assert that with read-only regcaches, the register's status must be known. If the regcache is read-only, and the register is not REG_VALID, memset the buffer. Return the register's status. (regcache_cooked_read_signed): Change return to enum register_status. Handle non-REG_VALID registers and return the register's status. (regcache_cooked_read_unsigned): Change return to enum register_status. Handle non-REG_VALID registers and return the register's status. (regcache_xfer_part, regcache_raw_read_part) (regcache_cooked_read_part): Change return to enum register_status. Return the register's status. (regcache_read_pc): Throw NOT_AVAILABLE_ERROR if the register is unavailable. (regcache_dump): Handle unavailable cooked registers. * frame.c (do_frame_register_read): Adjust interface to match regcache_cooked_read_ftype. * gdbarch.sh (pseudo_register_read): Change return to enum register_status. * gdbarch.h, gdbarch.c: Regenerate. * i386-tdep.h (i386_pseudo_register_read): Change return to enum register_status. * i386-tdep.c (i386_pseudo_register_read): Change return to enum register_status. If reading a raw register indicates the raw register is not valid, return the raw register's status, otherwise, return REG_VALID. * amd64-tdep.c (amd64_pseudo_register_read): Change return to enum register_status. Handle non-REG_VALID raw registers and return the register's status. * arm-tdep.c (arm_neon_quad_read) (arm_pseudo_read): Change return to enum register_status. Handle non-REG_VALID raw registers and return the register's status. * avr-tdep.c (avr_pseudo_register_read): Ditto. * frv-tdep.c (frv_pseudo_register_read): Ditto. * h8300-tdep.c (h8300_pseudo_register_read): Ditto. * hppa-tdep.c (hppa_pseudo_register_read): Ditto. * m32c-tdep.c (m32c_move_reg_t): Change return to enum register_status. (m32c_raw_read, m32c_raw_write, m32c_banked_read) (m32c_banked_write, m32c_sb_read, m32c_sb_write, m32c_part_read) (m32c_part_write, m32c_cat_read, m32c_cat_write) (m32c_r3r2r1r0_read, m32c_r3r2r1r0_write) (m32c_pseudo_register_read): Change return to enum register_status. Adjust. * m68hc11-tdep.c (m68hc11_pseudo_register_read): Change return to enum register_status. Return the register's status. * mep-tdep.c (mep_pseudo_cr32_read): Change return to enum register_status. Return the register's status. (mep_pseudo_cr64_read, mep_pseudo_register_read): Ditto. * mips-tdep.c (mips_pseudo_register_read): Ditto. * mt-tdep.c (mt_pseudo_register_read): Ditto. * rs6000-tdep.c (move_ev_register_func): New typedef. (e500_move_ev_register): Use it. Change return to enum register_status. Return the register's status. (do_regcache_raw_read): New function. (do_regcache_raw_write): New function. (e500_pseudo_register_read): Change return to enum register_status. Return the register's status. Use do_regcache_raw_read. (e500_pseudo_register_write): Adjust. Use do_regcache_raw_write. (dfp_pseudo_register_read): Change return to enum register_status. Return the register's status. (vsx_pseudo_register_read): Ditto. (efpr_pseudo_register_read): Ditto. (rs6000_pseudo_register_read): Ditto. * s390-tdep.c (s390_pseudo_register_read): Change return to enum register_status. Return the register's status. * sh64-tdep.c (pseudo_register_read_portions): New function. (sh64_pseudo_register_read): Change return to enum register_status. Use pseudo_register_read_portions. Return the register's status. * ia64-tdep.c (ia64_pseudo_register_read): Change return to enum register_status. Return the register's status. * sh-tdep.c (pseudo_register_read_portions): New function. (sh_pseudo_register_read): Change return to enum register_status. Use pseudo_register_read_portions. Return the register's status. * sparc-tdep.c (sparc32_pseudo_register_read): Change return to enum register_status. Return the register's status. * sparc64-tdep.c (sparc64_pseudo_register_read): Ditto. * spu-tdep.c (spu_pseudo_register_read_spu) (spu_pseudo_register_read): Ditto. * xtensa-tdep.c (xtensa_register_read_masked) (xtensa_pseudo_register_read): Ditto. * bfin-tdep.c (bfin_pseudo_register_read): Ditto.
Diffstat (limited to 'gdb/rs6000-tdep.c')
-rw-r--r--gdb/rs6000-tdep.c119
1 files changed, 77 insertions, 42 deletions
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 6ac3e8d..b8c87fb 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -2536,6 +2536,11 @@ rs6000_value_to_register (struct frame_info *frame,
put_frame_register (frame, regnum, to);
}
+ /* The type of a function that moves the value of REG between CACHE
+ or BUF --- in either direction. */
+typedef enum register_status (*move_ev_register_func) (struct regcache *,
+ int, void *);
+
/* 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
@@ -2559,16 +2564,16 @@ rs6000_value_to_register (struct frame_info *frame,
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, gdb_byte *buf),
- struct regcache *regcache, int ev_reg,
- gdb_byte *buffer)
+
+static enum register_status
+e500_move_ev_register (move_ev_register_func move,
+ 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;
gdb_byte *byte_buffer = buffer;
+ enum register_status status;
gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
@@ -2576,55 +2581,80 @@ e500_move_ev_register (void (*move) (struct regcache *regcache,
if (gdbarch_byte_order (arch) == 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);
+ status = move (regcache, tdep->ppc_ev0_upper_regnum + reg_index,
+ byte_buffer);
+ if (status == REG_VALID)
+ status = 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);
+ status = move (regcache, tdep->ppc_gp0_regnum + reg_index, byte_buffer);
+ if (status == REG_VALID)
+ status = move (regcache, tdep->ppc_ev0_upper_regnum + reg_index,
+ byte_buffer + 4);
}
+
+ return status;
}
-static void
+static enum register_status
+do_regcache_raw_read (struct regcache *regcache, int regnum, void *buffer)
+{
+ return regcache_raw_read (regcache, regnum, buffer);
+}
+
+static enum register_status
+do_regcache_raw_write (struct regcache *regcache, int regnum, void *buffer)
+{
+ regcache_raw_write (regcache, regnum, buffer);
+
+ return REG_VALID;
+}
+
+static enum register_status
e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
- e500_move_ev_register (regcache_raw_read, regcache, reg_nr, buffer);
+ return e500_move_ev_register (do_regcache_raw_read, regcache, reg_nr, buffer);
}
static void
e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, const gdb_byte *buffer)
{
- e500_move_ev_register ((void (*) (struct regcache *, int, gdb_byte *))
- regcache_raw_write,
- regcache, reg_nr, (gdb_byte *) buffer);
+ e500_move_ev_register (do_regcache_raw_write, regcache,
+ reg_nr, (void *) buffer);
}
/* Read method for DFP pseudo-registers. */
-static void
+static enum register_status
dfp_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+ enum register_status status;
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
/* Read two FP registers to form a whole dl register. */
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index, buffer);
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index + 1, buffer + 8);
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index, buffer);
+ if (status == REG_VALID)
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index + 1, buffer + 8);
}
else
{
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index + 1, buffer + 8);
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- 2 * reg_index, buffer);
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index + 1, buffer + 8);
+ if (status == REG_VALID)
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index, buffer);
}
+
+ return status;
}
/* Write method for DFP pseudo-registers. */
@@ -2654,33 +2684,38 @@ dfp_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
}
/* Read method for POWER7 VSX pseudo-registers. */
-static void
+static enum register_status
vsx_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+ enum register_status status;
/* Read the portion that overlaps the VMX registers. */
if (reg_index > 31)
- regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
- reg_index - 32, buffer);
+ status = regcache_raw_read (regcache, tdep->ppc_vr0_regnum +
+ reg_index - 32, buffer);
else
/* Read the portion that overlaps the FPR registers. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- reg_index, buffer);
- regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
- reg_index, buffer + 8);
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ reg_index, buffer);
+ if (status == REG_VALID)
+ status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
+ reg_index, buffer + 8);
}
else
{
- regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
- reg_index, buffer + 8);
- regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
- reg_index, buffer);
+ status = regcache_raw_read (regcache, tdep->ppc_fp0_regnum +
+ reg_index, buffer + 8);
+ if (status == REG_VALID)
+ status = regcache_raw_read (regcache, tdep->ppc_vsr0_upper_regnum +
+ reg_index, buffer);
}
+
+ return status;
}
/* Write method for POWER7 VSX pseudo-registers. */
@@ -2714,7 +2749,7 @@ vsx_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
}
/* Read method for POWER7 Extended FP pseudo-registers. */
-static void
+static enum register_status
efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
@@ -2722,8 +2757,8 @@ efpr_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
/* Read the portion that overlaps the VMX register. */
- regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0,
- register_size (gdbarch, reg_nr), buffer);
+ return regcache_raw_read_part (regcache, tdep->ppc_vr0_regnum + reg_index, 0,
+ register_size (gdbarch, reg_nr), buffer);
}
/* Write method for POWER7 Extended FP pseudo-registers. */
@@ -2739,7 +2774,7 @@ efpr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
register_size (gdbarch, reg_nr), buffer);
}
-static void
+static enum register_status
rs6000_pseudo_register_read (struct gdbarch *gdbarch,
struct regcache *regcache,
int reg_nr, gdb_byte *buffer)
@@ -2750,13 +2785,13 @@ rs6000_pseudo_register_read (struct gdbarch *gdbarch,
gdb_assert (regcache_arch == gdbarch);
if (IS_SPE_PSEUDOREG (tdep, reg_nr))
- e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+ return e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
- dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+ return dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
- vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+ return vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
- efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+ return efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
else
internal_error (__FILE__, __LINE__,
_("rs6000_pseudo_register_read: "