/* Target-dependent code for GDB, the GNU debugger.
Copyright (C) 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GDB.
#include "features/rs6000/powerpc-e500.c"
#include "features/rs6000/rs6000.c"
+/* Determine if regnum is an SPE pseudo-register. */
+#define IS_SPE_PSEUDOREG(tdep, regnum) ((tdep)->ppc_ev0_regnum >= 0 \
+ && (regnum) >= (tdep)->ppc_ev0_regnum \
+ && (regnum) < (tdep)->ppc_ev0_regnum + 32)
+
+/* Determine if regnum is a decimal float pseudo-register. */
+#define IS_DFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_dl0_regnum >= 0 \
+ && (regnum) >= (tdep)->ppc_dl0_regnum \
+ && (regnum) < (tdep)->ppc_dl0_regnum + 16)
+
/* The list of available "set powerpc ..." and "show powerpc ..."
commands. */
static struct cmd_list_element *setpowerpccmdlist = NULL;
static CORE_ADDR branch_dest (struct frame_info *frame, int opcode,
int instr, CORE_ADDR pc, CORE_ADDR safety);
-static CORE_ADDR skip_prologue (CORE_ADDR, CORE_ADDR,
+static CORE_ADDR skip_prologue (struct gdbarch *, CORE_ADDR, CORE_ADDR,
struct rs6000_framedata *);
/* Is REGNO an AltiVec register? Return 1 if so, 0 otherwise. */
int
-altivec_register_p (int regno)
+altivec_register_p (struct gdbarch *gdbarch, int regno)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (tdep->ppc_vr0_regnum < 0 || tdep->ppc_vrsave_regnum < 0)
return 0;
else
/* Return true if REGNO is an SPE register, false otherwise. */
int
-spe_register_p (int regno)
+spe_register_p (struct gdbarch *gdbarch, int regno)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* Is it a reference to EV0 -- EV31, and do we have those? */
- if (tdep->ppc_ev0_regnum >= 0
- && tdep->ppc_ev31_regnum >= 0
- && tdep->ppc_ev0_regnum <= regno && regno <= tdep->ppc_ev31_regnum)
+ if (IS_SPE_PSEUDOREG (tdep, regno))
return 1;
/* Is it a reference to one of the raw upper GPR halves? */
/* Given a GDB register number REG, return the corresponding SIM
register number. */
static int
-rs6000_register_sim_regno (int reg)
+rs6000_register_sim_regno (struct gdbarch *gdbarch, int reg)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int sim_regno;
if (tdep->sim_regno == NULL)
- init_sim_regno_table (current_gdbarch);
+ init_sim_regno_table (gdbarch);
gdb_assert (0 <= reg
- && reg <= gdbarch_num_regs (current_gdbarch)
- + gdbarch_num_pseudo_regs (current_gdbarch));
+ && reg <= gdbarch_num_regs (gdbarch)
+ + gdbarch_num_pseudo_regs (gdbarch));
sim_regno = tdep->sim_regno[reg];
if (sim_regno >= 0)
}
static CORE_ADDR
-rs6000_skip_prologue (CORE_ADDR pc)
+rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
struct rs6000_framedata frame;
CORE_ADDR limit_pc, func_addr;
if (limit_pc == 0)
limit_pc = pc + 100; /* Magic. */
- pc = skip_prologue (pc, limit_pc, &frame);
+ pc = skip_prologue (gdbarch, pc, limit_pc, &frame);
return pc;
}
*/
static CORE_ADDR
-skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
+skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
+ struct rs6000_framedata *fdata)
{
CORE_ADDR orig_pc = pc;
CORE_ADDR last_prologue_pc = pc;
int prev_insn_was_prologue_insn = 1;
int num_skip_non_prologue_insns = 0;
int r0_contains_arg = 0;
- const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
memset (fdata, 0, sizeof (struct rs6000_framedata));
fdata->saved_gpr = -1;
return "";
/* Check if the SPE pseudo registers are available. */
- if (tdep->ppc_ev0_regnum >= 0
- && tdep->ppc_ev0_regnum <= regno
- && regno < tdep->ppc_ev0_regnum + ppc_num_gprs)
+ if (IS_SPE_PSEUDOREG (tdep, regno))
{
static const char *const spe_regnames[] = {
"ev0", "ev1", "ev2", "ev3", "ev4", "ev5", "ev6", "ev7",
return spe_regnames[regno - tdep->ppc_ev0_regnum];
}
+ /* Check if the decimal128 pseudo-registers are available. */
+ if (IS_DFP_PSEUDOREG (tdep, regno))
+ {
+ static const char *const dfp128_regnames[] = {
+ "dl0", "dl1", "dl2", "dl3",
+ "dl4", "dl5", "dl6", "dl7",
+ "dl8", "dl9", "dl10", "dl11",
+ "dl12", "dl13", "dl14", "dl15"
+ };
+ return dfp128_regnames[regno - tdep->ppc_dl0_regnum];
+ }
+
return tdesc_register_name (gdbarch, regno);
}
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* These are the only pseudo-registers we support. */
- gdb_assert (tdep->ppc_ev0_regnum >= 0
- && regnum >= tdep->ppc_ev0_regnum
- && regnum < tdep->ppc_ev0_regnum + 32);
+ gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
+ || IS_DFP_PSEUDOREG (tdep, regnum));
- return rs6000_builtin_type_vec64 (gdbarch);
+ /* These are the e500 pseudo-registers. */
+ if (IS_SPE_PSEUDOREG (tdep, regnum))
+ return rs6000_builtin_type_vec64 (gdbarch);
+ else
+ /* Could only be the ppc decimal128 pseudo-registers. */
+ return builtin_type (gdbarch)->builtin_declong;
}
/* Is REGNUM a member of REGGROUP? */
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
/* These are the only pseudo-registers we support. */
- gdb_assert (tdep->ppc_ev0_regnum >= 0
- && regnum >= tdep->ppc_ev0_regnum
- && regnum < tdep->ppc_ev0_regnum + 32);
+ gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
+ || IS_DFP_PSEUDOREG (tdep, regnum));
- if (group == all_reggroup || group == vector_reggroup)
- return 1;
+ /* These are the e500 pseudo-registers. */
+ if (IS_SPE_PSEUDOREG (tdep, regnum))
+ return group == all_reggroup || group == vector_reggroup;
else
- return 0;
+ /* Could only be the ppc decimal128 pseudo-registers. */
+ return group == all_reggroup || group == float_reggroup;
}
/* The register format for RS/6000 floating point registers is always
double, we need a conversion if the memory format is float. */
static int
-rs6000_convert_register_p (int regnum, struct type *type)
+rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum,
+ struct type *type)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
return (tdep->ppc_fp0_regnum >= 0
&& regnum >= tdep->ppc_fp0_regnum
int reg_index;
gdb_byte *byte_buffer = buffer;
- gdb_assert (tdep->ppc_ev0_regnum <= ev_reg
- && ev_reg < tdep->ppc_ev0_regnum + ppc_num_gprs);
+ gdb_assert (IS_SPE_PSEUDOREG (tdep, ev_reg));
reg_index = ev_reg - tdep->ppc_ev0_regnum;
static void
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);
+}
+
+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);
+}
+
+/* Read method for PPC pseudo-registers. Currently this is handling the
+ 16 decimal128 registers that map into 16 pairs of FP registers. */
+static void
+ppc_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;
+
+ 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);
+ }
+ 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);
+ }
+}
+
+/* Write method for PPC pseudo-registers. Currently this is handling the
+ 16 decimal128 registers that map into 16 pairs of FP registers. */
+static void
+ppc_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+ int reg_nr, const gdb_byte *buffer)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+
+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ {
+ /* Write each half of the dl register into a separate
+ FP register. */
+ regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index, buffer);
+ regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index + 1, buffer + 8);
+ }
+ else
+ {
+ regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index + 1, buffer + 8);
+ regcache_raw_write (regcache, tdep->ppc_fp0_regnum +
+ 2 * reg_index, buffer);
+ }
+}
+
+static void
+rs6000_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+ int reg_nr, gdb_byte *buffer)
{
struct gdbarch *regcache_arch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
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);
+
+ if (IS_SPE_PSEUDOREG (tdep, reg_nr))
+ e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+ else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+ ppc_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
else
internal_error (__FILE__, __LINE__,
- _("e500_pseudo_register_read: "
- "called on unexpected register '%s' (%d)"),
- gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+ _("rs6000_pseudo_register_read: "
+ "called on unexpected register '%s' (%d)"),
+ gdbarch_register_name (gdbarch, reg_nr), reg_nr);
}
static void
-e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
- int reg_nr, const gdb_byte *buffer)
+rs6000_pseudo_register_write (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ int reg_nr, const gdb_byte *buffer)
{
struct gdbarch *regcache_arch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
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, gdb_byte *))
- regcache_raw_write,
- regcache, reg_nr, (gdb_byte *) buffer);
+
+ if (IS_SPE_PSEUDOREG (tdep, reg_nr))
+ e500_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
+ else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+ ppc_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
else
internal_error (__FILE__, __LINE__,
- _("e500_pseudo_register_read: "
- "called on unexpected register '%s' (%d)"),
- gdbarch_register_name (gdbarch, reg_nr), reg_nr);
+ _("rs6000_pseudo_register_write: "
+ "called on unexpected register '%s' (%d)"),
+ gdbarch_register_name (gdbarch, reg_nr), reg_nr);
}
/* Convert a DBX STABS register number to a GDB register number. */
static int
-rs6000_stab_reg_to_regnum (int num)
+rs6000_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (0 <= num && num <= 31)
return tdep->ppc_gp0_regnum + num;
/* Convert a Dwarf 2 register number to a GDB register number. */
static int
-rs6000_dwarf2_reg_to_regnum (int num)
+rs6000_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int num)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (0 <= num && num <= 31)
return tdep->ppc_gp0_regnum + num;
if (!info->disassembler_options)
info->disassembler_options = "any";
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ if (info->endian == BFD_ENDIAN_BIG)
return print_insn_big_powerpc (memaddr, info);
else
return print_insn_little_powerpc (memaddr, info);
func = frame_func_unwind (next_frame, NORMAL_FRAME);
pc = frame_pc_unwind (next_frame);
- skip_prologue (func, pc, &fdata);
+ skip_prologue (gdbarch, func, pc, &fdata);
/* Figure out the parent's stack pointer. */
/* if != -1, fdata.saved_ev is the smallest number of saved_ev.
All vr's from saved_ev to ev31 are saved. ????? */
- if (tdep->ppc_ev0_regnum != -1 && tdep->ppc_ev31_regnum != -1)
+ if (tdep->ppc_ev0_regnum != -1)
{
if (fdata.saved_ev >= 0)
{
}
/* Handle PC register and Stack Pointer correctly. */
- if (regnum == gdbarch_pc_regnum (current_gdbarch))
+ if (regnum == gdbarch_pc_regnum (gdbarch))
reg->how = DWARF2_FRAME_REG_RA;
- else if (regnum == gdbarch_sp_regnum (current_gdbarch))
+ else if (regnum == gdbarch_sp_regnum (gdbarch))
reg->how = DWARF2_FRAME_REG_CFA;
}
enum auto_boolean soft_float_flag = powerpc_soft_float_global;
int soft_float;
enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
- int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0;
+ int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0;
int tdesc_wordsize = -1;
const struct target_desc *tdesc = info.target_desc;
struct tdesc_arch_data *tdesc_data = NULL;
- int num_sprs = 0;
+ int num_pseudoregs = 0;
from_xcoff_exec = info.abfd && info.abfd->format == bfd_object &&
bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour;
else
have_fpu = 0;
+ /* The DFP pseudo-registers will be available when there are floating
+ point registers. */
+ have_dfp = have_fpu;
+
feature = tdesc_find_feature (tdesc,
"org.gnu.gdb.power.altivec");
if (feature != NULL)
else
tdep->lr_frame_offset = 8;
- if (have_spe)
+ if (have_spe || have_dfp)
{
- set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read);
- set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write);
+ set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
+ set_gdbarch_pseudo_register_write (gdbarch, rs6000_pseudo_register_write);
}
set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
else
set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc);
- set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS + num_sprs);
- set_gdbarch_num_pseudo_regs (gdbarch, have_spe ? 32 : 0);
+ set_gdbarch_num_regs (gdbarch, PPC_NUM_REGS);
+
+ if (have_spe)
+ num_pseudoregs += 32;
+ if (have_dfp)
+ num_pseudoregs += 16;
+
+ set_gdbarch_num_pseudo_regs (gdbarch, num_pseudoregs);
set_gdbarch_ptr_bit (gdbarch, wordsize * TARGET_CHAR_BIT);
set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
/* Recording the numbering of pseudo registers. */
tdep->ppc_ev0_regnum = have_spe ? gdbarch_num_regs (gdbarch) : -1;
- tdep->ppc_ev31_regnum = have_spe ? tdep->ppc_ev0_regnum + 31 : -1;
+
+ /* Set the register number for _Decimal128 pseudo-registers. */
+ tdep->ppc_dl0_regnum = have_dfp? gdbarch_num_regs (gdbarch) : -1;
+
+ if (have_dfp && have_spe)
+ /* Put the _Decimal128 pseudo-registers after the SPE registers. */
+ tdep->ppc_dl0_regnum += 32;
return gdbarch;
}