/* Target-dependent code for GDB, the GNU debugger.
- Copyright (C) 1986-2018 Free Software Foundation, Inc.
+ Copyright (C) 1986-2019 Free Software Foundation, Inc.
This file is part of GDB.
&& (regnum) >= (tdep)->ppc_dl0_regnum \
&& (regnum) < (tdep)->ppc_dl0_regnum + 16)
+/* Determine if regnum is a "vX" alias for the raw "vrX" vector
+ registers. */
+#define IS_V_ALIAS_PSEUDOREG(tdep, regnum) (\
+ (tdep)->ppc_v0_alias_regnum >= 0 \
+ && (regnum) >= (tdep)->ppc_v0_alias_regnum \
+ && (regnum) < (tdep)->ppc_v0_alias_regnum + ppc_num_vrs)
+
/* Determine if regnum is a POWER7 VSX register. */
#define IS_VSX_PSEUDOREG(tdep, regnum) ((tdep)->ppc_vsr0_regnum >= 0 \
&& (regnum) >= (tdep)->ppc_vsr0_regnum \
&& (regnum) >= (tdep)->ppc_efpr0_regnum \
&& (regnum) < (tdep)->ppc_efpr0_regnum + ppc_num_efprs)
+/* Determine if regnum is a checkpointed decimal float
+ pseudo-register. */
+#define IS_CDFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cdl0_regnum >= 0 \
+ && (regnum) >= (tdep)->ppc_cdl0_regnum \
+ && (regnum) < (tdep)->ppc_cdl0_regnum + 16)
+
+/* Determine if regnum is a Checkpointed POWER7 VSX register. */
+#define IS_CVSX_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cvsr0_regnum >= 0 \
+ && (regnum) >= (tdep)->ppc_cvsr0_regnum \
+ && (regnum) < (tdep)->ppc_cvsr0_regnum + ppc_num_vsrs)
+
+/* Determine if regnum is a Checkpointed POWER7 Extended FP register. */
+#define IS_CEFP_PSEUDOREG(tdep, regnum) ((tdep)->ppc_cefpr0_regnum >= 0 \
+ && (regnum) >= (tdep)->ppc_cefpr0_regnum \
+ && (regnum) < (tdep)->ppc_cefpr0_regnum + ppc_num_efprs)
+
/* Holds the current set of options to be passed to the disassembler. */
static char *powerpc_disassembler_options;
else
{
- unsigned int all_mask = ~((1U << fdata->saved_gpr) - 1);
-
/* Not a recognized prologue instruction.
Handle optimizer code motions into the prologue by continuing
the search if we have no valid frame yet or if the return
address is not yet saved in the frame. Also skip instructions
if some of the GPRs expected to be saved are not yet saved. */
if (fdata->frameless == 0 && fdata->nosavedpc == 0
- && (fdata->gpr_mask & all_mask) == all_mask)
- break;
+ && fdata->saved_gpr != -1)
+ {
+ unsigned int all_mask = ~((1U << fdata->saved_gpr) - 1);
+
+ if ((fdata->gpr_mask & all_mask) == all_mask)
+ break;
+ }
if (op == 0x4e800020 /* blr */
|| op == 0x4e800420) /* bctr */
&& regno < tdep->ppc_vsr0_upper_regnum + ppc_num_gprs)
return "";
+ /* Hide the upper halves of the cvs0~cvs31 registers. */
+ if (PPC_CVSR0_UPPER_REGNUM <= regno
+ && regno < PPC_CVSR0_UPPER_REGNUM + ppc_num_gprs)
+ return "";
+
/* Check if the SPE pseudo registers are available. */
if (IS_SPE_PSEUDOREG (tdep, regno))
{
return dfp128_regnames[regno - tdep->ppc_dl0_regnum];
}
+ /* Check if this is a vX alias for a raw vrX vector register. */
+ if (IS_V_ALIAS_PSEUDOREG (tdep, regno))
+ {
+ static const char *const vector_alias_regnames[] = {
+ "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
+ "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
+ "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
+ "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
+ };
+ return vector_alias_regnames[regno - tdep->ppc_v0_alias_regnum];
+ }
+
/* Check if this is a VSX pseudo-register. */
if (IS_VSX_PSEUDOREG (tdep, regno))
{
return efpr_regnames[regno - tdep->ppc_efpr0_regnum];
}
+ /* Check if this is a Checkpointed DFP pseudo-register. */
+ if (IS_CDFP_PSEUDOREG (tdep, regno))
+ {
+ static const char *const cdfp128_regnames[] = {
+ "cdl0", "cdl1", "cdl2", "cdl3",
+ "cdl4", "cdl5", "cdl6", "cdl7",
+ "cdl8", "cdl9", "cdl10", "cdl11",
+ "cdl12", "cdl13", "cdl14", "cdl15"
+ };
+ return cdfp128_regnames[regno - tdep->ppc_cdl0_regnum];
+ }
+
+ /* Check if this is a Checkpointed VSX pseudo-register. */
+ if (IS_CVSX_PSEUDOREG (tdep, regno))
+ {
+ static const char *const cvsx_regnames[] = {
+ "cvs0", "cvs1", "cvs2", "cvs3", "cvs4", "cvs5", "cvs6", "cvs7",
+ "cvs8", "cvs9", "cvs10", "cvs11", "cvs12", "cvs13", "cvs14",
+ "cvs15", "cvs16", "cvs17", "cvs18", "cvs19", "cvs20", "cvs21",
+ "cvs22", "cvs23", "cvs24", "cvs25", "cvs26", "cvs27", "cvs28",
+ "cvs29", "cvs30", "cvs31", "cvs32", "cvs33", "cvs34", "cvs35",
+ "cvs36", "cvs37", "cvs38", "cvs39", "cvs40", "cvs41", "cvs42",
+ "cvs43", "cvs44", "cvs45", "cvs46", "cvs47", "cvs48", "cvs49",
+ "cvs50", "cvs51", "cvs52", "cvs53", "cvs54", "cvs55", "cvs56",
+ "cvs57", "cvs58", "cvs59", "cvs60", "cvs61", "cvs62", "cvs63"
+ };
+ return cvsx_regnames[regno - tdep->ppc_cvsr0_regnum];
+ }
+
+ /* Check if the this is a Checkpointed Extended FP pseudo-register. */
+ if (IS_CEFP_PSEUDOREG (tdep, regno))
+ {
+ static const char *const cefpr_regnames[] = {
+ "cf32", "cf33", "cf34", "cf35", "cf36", "cf37", "cf38",
+ "cf39", "cf40", "cf41", "cf42", "cf43", "cf44", "cf45",
+ "cf46", "cf47", "cf48", "cf49", "cf50", "cf51",
+ "cf52", "cf53", "cf54", "cf55", "cf56", "cf57",
+ "cf58", "cf59", "cf60", "cf61", "cf62", "cf63"
+ };
+ return cefpr_regnames[regno - tdep->ppc_cefpr0_regnum];
+ }
+
return tdesc_register_name (gdbarch, regno);
}
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- /* These are the only pseudo-registers we support. */
- gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
- || IS_DFP_PSEUDOREG (tdep, regnum)
- || IS_VSX_PSEUDOREG (tdep, regnum)
- || IS_EFP_PSEUDOREG (tdep, regnum));
-
/* These are the e500 pseudo-registers. */
if (IS_SPE_PSEUDOREG (tdep, regnum))
return rs6000_builtin_type_vec64 (gdbarch);
- else if (IS_DFP_PSEUDOREG (tdep, regnum))
+ else if (IS_DFP_PSEUDOREG (tdep, regnum)
+ || IS_CDFP_PSEUDOREG (tdep, regnum))
/* PPC decimal128 pseudo-registers. */
return builtin_type (gdbarch)->builtin_declong;
- else if (IS_VSX_PSEUDOREG (tdep, regnum))
+ else if (IS_V_ALIAS_PSEUDOREG (tdep, regnum))
+ return gdbarch_register_type (gdbarch,
+ tdep->ppc_vr0_regnum
+ + (regnum
+ - tdep->ppc_v0_alias_regnum));
+ else if (IS_VSX_PSEUDOREG (tdep, regnum)
+ || IS_CVSX_PSEUDOREG (tdep, regnum))
/* POWER7 VSX pseudo-registers. */
return rs6000_builtin_type_vec128 (gdbarch);
- else
+ else if (IS_EFP_PSEUDOREG (tdep, regnum)
+ || IS_CEFP_PSEUDOREG (tdep, regnum))
/* POWER7 Extended FP pseudo-registers. */
return builtin_type (gdbarch)->builtin_double;
+ else
+ internal_error (__FILE__, __LINE__,
+ _("rs6000_pseudo_register_type: "
+ "called on unexpected register '%s' (%d)"),
+ gdbarch_register_name (gdbarch, regnum), regnum);
}
-/* Is REGNUM a member of REGGROUP? */
+/* Check if REGNUM is a member of REGGROUP. We only need to handle
+ the vX aliases for the vector registers by always returning false
+ to avoid duplicated information in "info register vector/all",
+ since the raw vrX registers will already show in these cases. For
+ other pseudo-registers we use the default membership function. */
+
static int
rs6000_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
struct reggroup *group)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- /* These are the only pseudo-registers we support. */
- gdb_assert (IS_SPE_PSEUDOREG (tdep, regnum)
- || IS_DFP_PSEUDOREG (tdep, regnum)
- || IS_VSX_PSEUDOREG (tdep, regnum)
- || IS_EFP_PSEUDOREG (tdep, regnum));
-
- /* These are the e500 pseudo-registers or the POWER7 VSX registers. */
- if (IS_SPE_PSEUDOREG (tdep, regnum) || IS_VSX_PSEUDOREG (tdep, regnum))
- return group == all_reggroup || group == vector_reggroup;
+ if (IS_V_ALIAS_PSEUDOREG (tdep, regnum))
+ return 0;
else
- /* PPC decimal128 or Extended FP pseudo-registers. */
- return group == all_reggroup || group == float_reggroup;
+ return default_register_reggroup_p (gdbarch, regnum, group);
}
/* The register format for RS/6000 floating point registers is always
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+ int reg_index, fp0;
enum register_status status;
+ if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+ {
+ reg_index = reg_nr - tdep->ppc_dl0_regnum;
+ fp0 = PPC_F0_REGNUM;
+ }
+ else
+ {
+ gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr));
+
+ reg_index = reg_nr - tdep->ppc_cdl0_regnum;
+ fp0 = PPC_CF0_REGNUM;
+ }
+
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
/* Read two FP registers to form a whole dl register. */
- status = regcache->raw_read (tdep->ppc_fp0_regnum +
- 2 * reg_index, buffer);
+ status = regcache->raw_read (fp0 + 2 * reg_index, buffer);
if (status == REG_VALID)
- status = regcache->raw_read (tdep->ppc_fp0_regnum +
- 2 * reg_index + 1, buffer + 8);
+ status = regcache->raw_read (fp0 + 2 * reg_index + 1,
+ buffer + 8);
}
else
{
- status = regcache->raw_read (tdep->ppc_fp0_regnum +
- 2 * reg_index + 1, buffer);
+ status = regcache->raw_read (fp0 + 2 * reg_index + 1, buffer);
if (status == REG_VALID)
- status = regcache->raw_read (tdep->ppc_fp0_regnum +
- 2 * reg_index, buffer + 8);
+ status = regcache->raw_read (fp0 + 2 * reg_index, buffer + 8);
}
return status;
int reg_nr, const gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int reg_index = reg_nr - tdep->ppc_dl0_regnum;
+ int reg_index, fp0;
+
+ if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+ {
+ reg_index = reg_nr - tdep->ppc_dl0_regnum;
+ fp0 = PPC_F0_REGNUM;
+ }
+ else
+ {
+ gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr));
+
+ reg_index = reg_nr - tdep->ppc_cdl0_regnum;
+ fp0 = PPC_CF0_REGNUM;
+ }
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
/* Write each half of the dl register into a separate
- FP register. */
- regcache->raw_write (tdep->ppc_fp0_regnum +
- 2 * reg_index, buffer);
- regcache->raw_write (tdep->ppc_fp0_regnum +
- 2 * reg_index + 1, buffer + 8);
+ FP register. */
+ regcache->raw_write (fp0 + 2 * reg_index, buffer);
+ regcache->raw_write (fp0 + 2 * reg_index + 1, buffer + 8);
}
else
{
- regcache->raw_write (tdep->ppc_fp0_regnum +
- 2 * reg_index + 1, buffer);
- regcache->raw_write (tdep->ppc_fp0_regnum +
- 2 * reg_index, buffer + 8);
+ regcache->raw_write (fp0 + 2 * reg_index + 1, buffer);
+ regcache->raw_write (fp0 + 2 * reg_index, buffer + 8);
}
}
+/* Read method for the vX aliases for the raw vrX registers. */
+
+static enum register_status
+v_alias_pseudo_register_read (struct gdbarch *gdbarch,
+ readable_regcache *regcache, int reg_nr,
+ gdb_byte *buffer)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
+
+ return regcache->raw_read (tdep->ppc_vr0_regnum
+ + (reg_nr - tdep->ppc_v0_alias_regnum),
+ buffer);
+}
+
+/* Write method for the vX aliases for the raw vrX registers. */
+
+static void
+v_alias_pseudo_register_write (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ int reg_nr, const gdb_byte *buffer)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
+
+ regcache->raw_write (tdep->ppc_vr0_regnum
+ + (reg_nr - tdep->ppc_v0_alias_regnum), buffer);
+}
+
/* Read method for POWER7 VSX pseudo-registers. */
static enum register_status
vsx_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+ int reg_index, vr0, fp0, vsr0_upper;
enum register_status status;
+ if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+ {
+ reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+ vr0 = PPC_VR0_REGNUM;
+ fp0 = PPC_F0_REGNUM;
+ vsr0_upper = PPC_VSR0_UPPER_REGNUM;
+ }
+ else
+ {
+ gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr));
+
+ reg_index = reg_nr - tdep->ppc_cvsr0_regnum;
+ vr0 = PPC_CVR0_REGNUM;
+ fp0 = PPC_CF0_REGNUM;
+ vsr0_upper = PPC_CVSR0_UPPER_REGNUM;
+ }
+
/* Read the portion that overlaps the VMX registers. */
if (reg_index > 31)
- status = regcache->raw_read (tdep->ppc_vr0_regnum +
- reg_index - 32, buffer);
+ status = regcache->raw_read (vr0 + reg_index - 32, buffer);
else
/* Read the portion that overlaps the FPR registers. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
- status = regcache->raw_read (tdep->ppc_fp0_regnum +
- reg_index, buffer);
+ status = regcache->raw_read (fp0 + reg_index, buffer);
if (status == REG_VALID)
- status = regcache->raw_read (tdep->ppc_vsr0_upper_regnum +
- reg_index, buffer + 8);
+ status = regcache->raw_read (vsr0_upper + reg_index,
+ buffer + 8);
}
else
{
- status = regcache->raw_read (tdep->ppc_fp0_regnum +
- reg_index, buffer + 8);
+ status = regcache->raw_read (fp0 + reg_index, buffer + 8);
if (status == REG_VALID)
- status = regcache->raw_read (tdep->ppc_vsr0_upper_regnum +
- reg_index, buffer);
+ status = regcache->raw_read (vsr0_upper + reg_index, buffer);
}
return status;
int reg_nr, const gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+ int reg_index, vr0, fp0, vsr0_upper;
+
+ if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+ {
+ reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+ vr0 = PPC_VR0_REGNUM;
+ fp0 = PPC_F0_REGNUM;
+ vsr0_upper = PPC_VSR0_UPPER_REGNUM;
+ }
+ else
+ {
+ gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr));
+
+ reg_index = reg_nr - tdep->ppc_cvsr0_regnum;
+ vr0 = PPC_CVR0_REGNUM;
+ fp0 = PPC_CF0_REGNUM;
+ vsr0_upper = PPC_CVSR0_UPPER_REGNUM;
+ }
/* Write the portion that overlaps the VMX registers. */
if (reg_index > 31)
- regcache->raw_write (tdep->ppc_vr0_regnum +
- reg_index - 32, buffer);
+ regcache->raw_write (vr0 + reg_index - 32, buffer);
else
/* Write the portion that overlaps the FPR registers. */
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
- regcache->raw_write (tdep->ppc_fp0_regnum +
- reg_index, buffer);
- regcache->raw_write (tdep->ppc_vsr0_upper_regnum +
- reg_index, buffer + 8);
+ regcache->raw_write (fp0 + reg_index, buffer);
+ regcache->raw_write (vsr0_upper + reg_index, buffer + 8);
}
else
{
- regcache->raw_write (tdep->ppc_fp0_regnum +
- reg_index, buffer + 8);
- regcache->raw_write (tdep->ppc_vsr0_upper_regnum +
- reg_index, buffer);
+ regcache->raw_write (fp0 + reg_index, buffer + 8);
+ regcache->raw_write (vsr0_upper + reg_index, buffer);
}
}
/* Read method for POWER7 Extended FP pseudo-registers. */
static enum register_status
-efpr_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
+efp_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
int reg_nr, gdb_byte *buffer)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+ int reg_index, vr0;
+
+ if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+ {
+ reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+ vr0 = PPC_VR0_REGNUM;
+ }
+ else
+ {
+ gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr));
+
+ reg_index = reg_nr - tdep->ppc_cefpr0_regnum;
+ vr0 = PPC_CVR0_REGNUM;
+ }
+
int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
/* Read the portion that overlaps the VMX register. */
- return regcache->raw_read_part (tdep->ppc_vr0_regnum + reg_index,
- offset, register_size (gdbarch, reg_nr),
+ return regcache->raw_read_part (vr0 + reg_index, offset,
+ register_size (gdbarch, reg_nr),
buffer);
}
/* Write method for POWER7 Extended FP pseudo-registers. */
static void
-efpr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+efp_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_efpr0_regnum;
+ int reg_index, vr0;
int offset = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? 0 : 8;
+ if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+ {
+ reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+ vr0 = PPC_VR0_REGNUM;
+ }
+ else
+ {
+ gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr));
+
+ reg_index = reg_nr - tdep->ppc_cefpr0_regnum;
+ vr0 = PPC_CVR0_REGNUM;
+
+ /* The call to raw_write_part fails silently if the initial read
+ of the read-update-write sequence returns an invalid status,
+ so we check this manually and throw an error if needed. */
+ regcache->raw_update (vr0 + reg_index);
+ if (regcache->get_register_status (vr0 + reg_index) != REG_VALID)
+ error (_("Cannot write to the checkpointed EFP register, "
+ "the corresponding vector register is unavailable."));
+ }
+
/* Write the portion that overlaps the VMX register. */
- regcache->raw_write_part (tdep->ppc_vr0_regnum + reg_index, offset,
+ regcache->raw_write_part (vr0 + reg_index, offset,
register_size (gdbarch, reg_nr), buffer);
}
if (IS_SPE_PSEUDOREG (tdep, reg_nr))
return e500_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
- else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+ else if (IS_DFP_PSEUDOREG (tdep, reg_nr)
+ || IS_CDFP_PSEUDOREG (tdep, reg_nr))
return dfp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
- else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+ else if (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr))
+ return v_alias_pseudo_register_read (gdbarch, regcache, reg_nr,
+ buffer);
+ else if (IS_VSX_PSEUDOREG (tdep, reg_nr)
+ || IS_CVSX_PSEUDOREG (tdep, reg_nr))
return vsx_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
- else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
- return efpr_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
+ else if (IS_EFP_PSEUDOREG (tdep, reg_nr)
+ || IS_CEFP_PSEUDOREG (tdep, reg_nr))
+ return efp_pseudo_register_read (gdbarch, regcache, reg_nr, buffer);
else
internal_error (__FILE__, __LINE__,
_("rs6000_pseudo_register_read: "
if (IS_SPE_PSEUDOREG (tdep, reg_nr))
e500_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
- else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+ else if (IS_DFP_PSEUDOREG (tdep, reg_nr)
+ || IS_CDFP_PSEUDOREG (tdep, reg_nr))
dfp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
- else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+ else if (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr))
+ v_alias_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
+ else if (IS_VSX_PSEUDOREG (tdep, reg_nr)
+ || IS_CVSX_PSEUDOREG (tdep, reg_nr))
vsx_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
- else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
- efpr_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
+ else if (IS_EFP_PSEUDOREG (tdep, reg_nr)
+ || IS_CEFP_PSEUDOREG (tdep, reg_nr))
+ efp_pseudo_register_write (gdbarch, regcache, reg_nr, buffer);
else
internal_error (__FILE__, __LINE__,
_("rs6000_pseudo_register_write: "
gdbarch_register_name (gdbarch, reg_nr), reg_nr);
}
+/* Set the register mask in AX with the registers that form the DFP or
+ checkpointed DFP pseudo-register REG_NR. */
+
+static void
+dfp_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int reg_index, fp0;
+
+ if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+ {
+ reg_index = reg_nr - tdep->ppc_dl0_regnum;
+ fp0 = PPC_F0_REGNUM;
+ }
+ else
+ {
+ gdb_assert (IS_CDFP_PSEUDOREG (tdep, reg_nr));
+
+ reg_index = reg_nr - tdep->ppc_cdl0_regnum;
+ fp0 = PPC_CF0_REGNUM;
+ }
+
+ ax_reg_mask (ax, fp0 + 2 * reg_index);
+ ax_reg_mask (ax, fp0 + 2 * reg_index + 1);
+}
+
+/* Set the register mask in AX with the raw vector register that
+ corresponds to its REG_NR alias. */
+
+static void
+v_alias_pseudo_register_collect (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ gdb_assert (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr));
+
+ ax_reg_mask (ax, tdep->ppc_vr0_regnum
+ + (reg_nr - tdep->ppc_v0_alias_regnum));
+}
+
+/* Set the register mask in AX with the registers that form the VSX or
+ checkpointed VSX pseudo-register REG_NR. */
+
+static void
+vsx_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int reg_index, vr0, fp0, vsr0_upper;
+
+ if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+ {
+ reg_index = reg_nr - tdep->ppc_vsr0_regnum;
+ vr0 = PPC_VR0_REGNUM;
+ fp0 = PPC_F0_REGNUM;
+ vsr0_upper = PPC_VSR0_UPPER_REGNUM;
+ }
+ else
+ {
+ gdb_assert (IS_CVSX_PSEUDOREG (tdep, reg_nr));
+
+ reg_index = reg_nr - tdep->ppc_cvsr0_regnum;
+ vr0 = PPC_CVR0_REGNUM;
+ fp0 = PPC_CF0_REGNUM;
+ vsr0_upper = PPC_CVSR0_UPPER_REGNUM;
+ }
+
+ if (reg_index > 31)
+ {
+ ax_reg_mask (ax, vr0 + reg_index - 32);
+ }
+ else
+ {
+ ax_reg_mask (ax, fp0 + reg_index);
+ ax_reg_mask (ax, vsr0_upper + reg_index);
+ }
+}
+
+/* Set the register mask in AX with the register that corresponds to
+ the EFP or checkpointed EFP pseudo-register REG_NR. */
+
+static void
+efp_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg_nr)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ int reg_index, vr0;
+
+ if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+ {
+ reg_index = reg_nr - tdep->ppc_efpr0_regnum;
+ vr0 = PPC_VR0_REGNUM;
+ }
+ else
+ {
+ gdb_assert (IS_CEFP_PSEUDOREG (tdep, reg_nr));
+
+ reg_index = reg_nr - tdep->ppc_cefpr0_regnum;
+ vr0 = PPC_CVR0_REGNUM;
+ }
+
+ ax_reg_mask (ax, vr0 + reg_index);
+}
+
static int
rs6000_ax_pseudo_register_collect (struct gdbarch *gdbarch,
struct agent_expr *ax, int reg_nr)
ax_reg_mask (ax, tdep->ppc_gp0_regnum + reg_index);
ax_reg_mask (ax, tdep->ppc_ev0_upper_regnum + reg_index);
}
- else if (IS_DFP_PSEUDOREG (tdep, reg_nr))
+ else if (IS_DFP_PSEUDOREG (tdep, reg_nr)
+ || IS_CDFP_PSEUDOREG (tdep, reg_nr))
{
- int reg_index = reg_nr - tdep->ppc_dl0_regnum;
- ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index);
- ax_reg_mask (ax, tdep->ppc_fp0_regnum + 2 * reg_index + 1);
+ dfp_ax_pseudo_register_collect (gdbarch, ax, reg_nr);
}
- else if (IS_VSX_PSEUDOREG (tdep, reg_nr))
+ else if (IS_V_ALIAS_PSEUDOREG (tdep, reg_nr))
{
- int reg_index = reg_nr - tdep->ppc_vsr0_regnum;
- if (reg_index > 31)
- {
- ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index - 32);
- }
- else
- {
- ax_reg_mask (ax, tdep->ppc_fp0_regnum + reg_index);
- ax_reg_mask (ax, tdep->ppc_vsr0_upper_regnum + reg_index);
- }
+ v_alias_pseudo_register_collect (gdbarch, ax, reg_nr);
+ }
+ else if (IS_VSX_PSEUDOREG (tdep, reg_nr)
+ || IS_CVSX_PSEUDOREG (tdep, reg_nr))
+ {
+ vsx_ax_pseudo_register_collect (gdbarch, ax, reg_nr);
}
- else if (IS_EFP_PSEUDOREG (tdep, reg_nr))
+ else if (IS_EFP_PSEUDOREG (tdep, reg_nr)
+ || IS_CEFP_PSEUDOREG (tdep, reg_nr))
{
- int reg_index = reg_nr - tdep->ppc_efpr0_regnum;
- ax_reg_mask (ax, tdep->ppc_vr0_regnum + reg_index);
+ efp_ax_pseudo_register_collect (gdbarch, ax, reg_nr);
}
else
internal_error (__FILE__, __LINE__,
}
\f
-static CORE_ADDR
-rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- return frame_unwind_register_unsigned (next_frame,
- gdbarch_pc_regnum (gdbarch));
-}
-
-static struct frame_id
-rs6000_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
- return frame_id_build (get_frame_register_unsigned
- (this_frame, gdbarch_sp_regnum (gdbarch)),
- get_frame_pc (this_frame));
-}
struct rs6000_frame_cache
{
cache->pc = 0;
cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- TRY
+ try
{
func = get_frame_func (this_frame);
cache->pc = func;
cache->base = get_frame_register_unsigned
(this_frame, gdbarch_sp_regnum (gdbarch));
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (ex.error != NOT_AVAILABLE_ERROR)
- throw_exception (ex);
+ throw;
return (struct rs6000_frame_cache *) (*this_cache);
}
- END_CATCH
/* If the function appears to be frameless, check a couple of likely
indicators that we have simply failed to find the frame setup.
(*this_cache) = cache;
cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
- TRY
+ try
{
/* At this point the stack looks as if we just entered the
function, and the return address is stored in LR. */
trad_frame_set_value (cache->saved_regs,
gdbarch_pc_regnum (gdbarch), lr);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (ex.error != NOT_AVAILABLE_ERROR)
- throw_exception (ex);
+ throw;
}
- END_CATCH
return cache;
}
case 570: /* Count Trailing Zeros Doubleword */
case 890: /* Extend-Sign Word and Shift Left Immediate (445) */
case 890 | 1: /* Extend-Sign Word and Shift Left Immediate (445) */
+
+ if (ext == 444 && tdep->ppc_ppr_regnum >= 0
+ && (PPC_RS (insn) == PPC_RA (insn))
+ && (PPC_RA (insn) == PPC_RB (insn))
+ && !PPC_RC (insn))
+ {
+ /* or Rx,Rx,Rx alters PRI in PPR. */
+ record_full_arch_list_add_reg (regcache, tdep->ppc_ppr_regnum);
+ return 0;
+ }
+
if (PPC_RC (insn))
record_full_arch_list_add_reg (regcache, tdep->ppc_cr_regnum);
record_full_arch_list_add_reg (regcache,
case 1: /* XER */
record_full_arch_list_add_reg (regcache, tdep->ppc_xer_regnum);
return 0;
+ case 3: /* DSCR */
+ if (tdep->ppc_dscr_regnum >= 0)
+ record_full_arch_list_add_reg (regcache, tdep->ppc_dscr_regnum);
+ return 0;
case 8: /* LR */
record_full_arch_list_add_reg (regcache, tdep->ppc_lr_regnum);
return 0;
case 256: /* VRSAVE */
record_full_arch_list_add_reg (regcache, tdep->ppc_vrsave_regnum);
return 0;
+ case 815: /* TAR */
+ if (tdep->ppc_tar_regnum >= 0)
+ record_full_arch_list_add_reg (regcache, tdep->ppc_tar_regnum);
+ return 0;
+ case 896:
+ case 898: /* PPR */
+ if (tdep->ppc_ppr_regnum >= 0)
+ record_full_arch_list_add_reg (regcache, tdep->ppc_ppr_regnum);
+ return 0;
}
goto UNKNOWN_OP;
enum powerpc_long_double_abi long_double_abi = POWERPC_LONG_DOUBLE_AUTO;
enum powerpc_vector_abi vector_abi = powerpc_vector_abi_global;
enum powerpc_elf_abi elf_abi = POWERPC_ELF_AUTO;
- int have_fpu = 1, have_spe = 0, have_mq = 0, have_altivec = 0, have_dfp = 0,
- have_vsx = 0;
+ int have_fpu = 0, have_spe = 0, have_mq = 0, have_altivec = 0;
+ int have_dfp = 0, have_vsx = 0, have_ppr = 0, have_dscr = 0;
+ int have_tar = 0, have_ebb = 0, have_pmu = 0, have_htm_spr = 0;
+ int have_htm_core = 0, have_htm_fpu = 0, have_htm_altivec = 0;
+ int have_htm_vsx = 0, have_htm_ppr = 0, have_htm_dscr = 0;
+ int have_htm_tar = 0;
int tdesc_wordsize = -1;
const struct target_desc *tdesc = info.target_desc;
struct tdesc_arch_data *tdesc_data = NULL;
valid_p &= tdesc_numbered_register (feature, tdesc_data,
PPC_VSR0_UPPER_REGNUM + i,
vsx_regs[i]);
- if (!valid_p)
+
+ if (!valid_p || !have_fpu || !have_altivec)
{
tdesc_data_cleanup (tdesc_data);
return NULL;
}
else
have_spe = 0;
+
+ /* Program Priority Register. */
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.ppr");
+ if (feature != NULL)
+ {
+ valid_p = 1;
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_PPR_REGNUM, "ppr");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_ppr = 1;
+ }
+ else
+ have_ppr = 0;
+
+ /* Data Stream Control Register. */
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.dscr");
+ if (feature != NULL)
+ {
+ valid_p = 1;
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_DSCR_REGNUM, "dscr");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_dscr = 1;
+ }
+ else
+ have_dscr = 0;
+
+ /* Target Address Register. */
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.tar");
+ if (feature != NULL)
+ {
+ valid_p = 1;
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_TAR_REGNUM, "tar");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_tar = 1;
+ }
+ else
+ have_tar = 0;
+
+ /* Event-based Branching Registers. */
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.ebb");
+ if (feature != NULL)
+ {
+ static const char *const ebb_regs[] = {
+ "bescr", "ebbhr", "ebbrr"
+ };
+
+ valid_p = 1;
+ for (i = 0; i < ARRAY_SIZE (ebb_regs); i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_BESCR_REGNUM + i,
+ ebb_regs[i]);
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_ebb = 1;
+ }
+ else
+ have_ebb = 0;
+
+ /* Subset of the ISA 2.07 Performance Monitor Registers provided
+ by Linux. */
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.linux.pmu");
+ if (feature != NULL)
+ {
+ valid_p = 1;
+
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_MMCR0_REGNUM,
+ "mmcr0");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_MMCR2_REGNUM,
+ "mmcr2");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_SIAR_REGNUM,
+ "siar");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_SDAR_REGNUM,
+ "sdar");
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_SIER_REGNUM,
+ "sier");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_pmu = 1;
+ }
+ else
+ have_pmu = 0;
+
+ /* Hardware Transactional Memory Registers. */
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.htm.spr");
+ if (feature != NULL)
+ {
+ static const char *const tm_spr_regs[] = {
+ "tfhar", "texasr", "tfiar"
+ };
+
+ valid_p = 1;
+ for (i = 0; i < ARRAY_SIZE (tm_spr_regs); i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_TFHAR_REGNUM + i,
+ tm_spr_regs[i]);
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+
+ have_htm_spr = 1;
+ }
+ else
+ have_htm_spr = 0;
+
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.htm.core");
+ if (feature != NULL)
+ {
+ static const char *const cgprs[] = {
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
+ "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14",
+ "cr15", "cr16", "cr17", "cr18", "cr19", "cr20", "cr21",
+ "cr22", "cr23", "cr24", "cr25", "cr26", "cr27", "cr28",
+ "cr29", "cr30", "cr31", "ccr", "cxer", "clr", "cctr"
+ };
+
+ valid_p = 1;
+
+ for (i = 0; i < ARRAY_SIZE (cgprs); i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_CR0_REGNUM + i,
+ cgprs[i]);
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+
+ have_htm_core = 1;
+ }
+ else
+ have_htm_core = 0;
+
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.htm.fpu");
+ if (feature != NULL)
+ {
+ valid_p = 1;
+
+ static const char *const cfprs[] = {
+ "cf0", "cf1", "cf2", "cf3", "cf4", "cf5", "cf6", "cf7",
+ "cf8", "cf9", "cf10", "cf11", "cf12", "cf13", "cf14", "cf15",
+ "cf16", "cf17", "cf18", "cf19", "cf20", "cf21", "cf22",
+ "cf23", "cf24", "cf25", "cf26", "cf27", "cf28", "cf29",
+ "cf30", "cf31", "cfpscr"
+ };
+
+ for (i = 0; i < ARRAY_SIZE (cfprs); i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_CF0_REGNUM + i,
+ cfprs[i]);
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_htm_fpu = 1;
+ }
+ else
+ have_htm_fpu = 0;
+
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.htm.altivec");
+ if (feature != NULL)
+ {
+ valid_p = 1;
+
+ static const char *const cvmx[] = {
+ "cvr0", "cvr1", "cvr2", "cvr3", "cvr4", "cvr5", "cvr6",
+ "cvr7", "cvr8", "cvr9", "cvr10", "cvr11", "cvr12", "cvr13",
+ "cvr14", "cvr15","cvr16", "cvr17", "cvr18", "cvr19", "cvr20",
+ "cvr21", "cvr22", "cvr23", "cvr24", "cvr25", "cvr26",
+ "cvr27", "cvr28", "cvr29", "cvr30", "cvr31", "cvscr",
+ "cvrsave"
+ };
+
+ for (i = 0; i < ARRAY_SIZE (cvmx); i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ PPC_CVR0_REGNUM + i,
+ cvmx[i]);
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_htm_altivec = 1;
+ }
+ else
+ have_htm_altivec = 0;
+
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.htm.vsx");
+ if (feature != NULL)
+ {
+ valid_p = 1;
+
+ static const char *const cvsx[] = {
+ "cvs0h", "cvs1h", "cvs2h", "cvs3h", "cvs4h", "cvs5h",
+ "cvs6h", "cvs7h", "cvs8h", "cvs9h", "cvs10h", "cvs11h",
+ "cvs12h", "cvs13h", "cvs14h", "cvs15h", "cvs16h", "cvs17h",
+ "cvs18h", "cvs19h", "cvs20h", "cvs21h", "cvs22h", "cvs23h",
+ "cvs24h", "cvs25h", "cvs26h", "cvs27h", "cvs28h", "cvs29h",
+ "cvs30h", "cvs31h"
+ };
+
+ for (i = 0; i < ARRAY_SIZE (cvsx); i++)
+ valid_p &= tdesc_numbered_register (feature, tdesc_data,
+ (PPC_CVSR0_UPPER_REGNUM
+ + i),
+ cvsx[i]);
+
+ if (!valid_p || !have_htm_fpu || !have_htm_altivec)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_htm_vsx = 1;
+ }
+ else
+ have_htm_vsx = 0;
+
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.htm.ppr");
+ if (feature != NULL)
+ {
+ valid_p = tdesc_numbered_register (feature, tdesc_data,
+ PPC_CPPR_REGNUM, "cppr");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_htm_ppr = 1;
+ }
+ else
+ have_htm_ppr = 0;
+
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.htm.dscr");
+ if (feature != NULL)
+ {
+ valid_p = tdesc_numbered_register (feature, tdesc_data,
+ PPC_CDSCR_REGNUM, "cdscr");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_htm_dscr = 1;
+ }
+ else
+ have_htm_dscr = 0;
+
+ feature = tdesc_find_feature (tdesc,
+ "org.gnu.gdb.power.htm.tar");
+ if (feature != NULL)
+ {
+ valid_p = tdesc_numbered_register (feature, tdesc_data,
+ PPC_CTAR_REGNUM, "ctar");
+
+ if (!valid_p)
+ {
+ tdesc_data_cleanup (tdesc_data);
+ return NULL;
+ }
+ have_htm_tar = 1;
+ }
+ else
+ have_htm_tar = 0;
}
/* If we have a 64-bit binary on a 32-bit target, complain. Also
tdep->ppc_ev0_upper_regnum = have_spe ? PPC_SPE_UPPER_GP0_REGNUM : -1;
tdep->ppc_acc_regnum = have_spe ? PPC_SPE_ACC_REGNUM : -1;
tdep->ppc_spefscr_regnum = have_spe ? PPC_SPE_FSCR_REGNUM : -1;
+ tdep->ppc_ppr_regnum = have_ppr ? PPC_PPR_REGNUM : -1;
+ tdep->ppc_dscr_regnum = have_dscr ? PPC_DSCR_REGNUM : -1;
+ tdep->ppc_tar_regnum = have_tar ? PPC_TAR_REGNUM : -1;
+ tdep->have_ebb = have_ebb;
+
+ /* If additional pmu registers are added, care must be taken when
+ setting new fields in the tdep below, to maintain compatibility
+ with features that only provide some of the registers. Currently
+ gdb access to the pmu registers is only supported in linux, and
+ linux only provides a subset of the pmu registers defined in the
+ architecture. */
+
+ tdep->ppc_mmcr0_regnum = have_pmu ? PPC_MMCR0_REGNUM : -1;
+ tdep->ppc_mmcr2_regnum = have_pmu ? PPC_MMCR2_REGNUM : -1;
+ tdep->ppc_siar_regnum = have_pmu ? PPC_SIAR_REGNUM : -1;
+ tdep->ppc_sdar_regnum = have_pmu ? PPC_SDAR_REGNUM : -1;
+ tdep->ppc_sier_regnum = have_pmu ? PPC_SIER_REGNUM : -1;
+
+ tdep->have_htm_spr = have_htm_spr;
+ tdep->have_htm_core = have_htm_core;
+ tdep->have_htm_fpu = have_htm_fpu;
+ tdep->have_htm_altivec = have_htm_altivec;
+ tdep->have_htm_vsx = have_htm_vsx;
+ tdep->ppc_cppr_regnum = have_htm_ppr ? PPC_CPPR_REGNUM : -1;
+ tdep->ppc_cdscr_regnum = have_htm_dscr ? PPC_CDSCR_REGNUM : -1;
+ tdep->ppc_ctar_regnum = have_htm_tar ? PPC_CTAR_REGNUM : -1;
set_gdbarch_pc_regnum (gdbarch, PPC_PC_REGNUM);
set_gdbarch_sp_regnum (gdbarch, PPC_R0_REGNUM + 1);
else
tdep->lr_frame_offset = 4;
- if (have_spe || have_dfp || have_vsx)
+ if (have_spe || have_dfp || have_altivec
+ || have_vsx || have_htm_fpu || have_htm_vsx)
{
set_gdbarch_pseudo_register_read (gdbarch, rs6000_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch,
num_pseudoregs += 32;
if (have_dfp)
num_pseudoregs += 16;
+ if (have_altivec)
+ num_pseudoregs += 32;
if (have_vsx)
/* Include both VSX and Extended FP registers. */
num_pseudoregs += 96;
+ if (have_htm_fpu)
+ num_pseudoregs += 16;
+ /* Include both checkpointed VSX and EFP registers. */
+ if (have_htm_vsx)
+ num_pseudoregs += 64 + 32;
set_gdbarch_num_pseudo_regs (gdbarch, num_pseudoregs);
case GDB_OSABI_LINUX:
case GDB_OSABI_NETBSD:
case GDB_OSABI_UNKNOWN:
- set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
- set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
break;
default:
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
- set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
- set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
}
/* Choose register numbers for all supported pseudo-registers. */
tdep->ppc_ev0_regnum = -1;
tdep->ppc_dl0_regnum = -1;
+ tdep->ppc_v0_alias_regnum = -1;
tdep->ppc_vsr0_regnum = -1;
tdep->ppc_efpr0_regnum = -1;
+ tdep->ppc_cdl0_regnum = -1;
+ tdep->ppc_cvsr0_regnum = -1;
+ tdep->ppc_cefpr0_regnum = -1;
cur_reg = gdbarch_num_regs (gdbarch);
tdep->ppc_dl0_regnum = cur_reg;
cur_reg += 16;
}
+ if (have_altivec)
+ {
+ tdep->ppc_v0_alias_regnum = cur_reg;
+ cur_reg += 32;
+ }
if (have_vsx)
{
tdep->ppc_vsr0_regnum = cur_reg;
tdep->ppc_efpr0_regnum = cur_reg;
cur_reg += 32;
}
+ if (have_htm_fpu)
+ {
+ tdep->ppc_cdl0_regnum = cur_reg;
+ cur_reg += 16;
+ }
+ if (have_htm_vsx)
+ {
+ tdep->ppc_cvsr0_regnum = cur_reg;
+ cur_reg += 64;
+ tdep->ppc_cefpr0_regnum = cur_reg;
+ cur_reg += 32;
+ }
gdb_assert (gdbarch_num_cooked_regs (gdbarch) == cur_reg);