return tdep->neon_quad_type;
}
+/* Return true if REGNUM is a Q pseudo register. Return false
+ otherwise.
+
+ REGNUM is the raw register number and not a pseudo-relative register
+ number. */
+
+static bool
+is_q_pseudo (struct gdbarch *gdbarch, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* Q pseudo registers are available for NEON (Q0~Q15). */
+ if (tdep->have_q_pseudos
+ && regnum >= tdep->q_pseudo_base
+ && regnum < (tdep->q_pseudo_base + tdep->q_pseudo_count))
+ return true;
+
+ return false;
+}
+
+/* Return true if REGNUM is a VFP S pseudo register. Return false
+ otherwise.
+
+ REGNUM is the raw register number and not a pseudo-relative register
+ number. */
+
+static bool
+is_s_pseudo (struct gdbarch *gdbarch, int regnum)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (tdep->have_s_pseudos
+ && regnum >= tdep->s_pseudo_base
+ && regnum < (tdep->s_pseudo_base + tdep->s_pseudo_count))
+ return true;
+
+ return false;
+}
+
/* Return the GDB type object for the "standard" data type of data in
register N. */
static struct type *
arm_register_type (struct gdbarch *gdbarch, int regnum)
{
- int num_regs = gdbarch_num_regs (gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (gdbarch_tdep (gdbarch)->have_vfp_pseudos
- && regnum >= num_regs && regnum < num_regs + 32)
+ if (is_s_pseudo (gdbarch, regnum))
return builtin_type (gdbarch)->builtin_float;
- if (gdbarch_tdep (gdbarch)->have_neon_pseudos
- && regnum >= num_regs + 32 && regnum < num_regs + 32 + 16)
+ if (is_q_pseudo (gdbarch, regnum))
return arm_neon_quad_type (gdbarch);
/* If the target description has register information, we are only
if (regnum >= ARM_D0_REGNUM && regnum < ARM_D0_REGNUM + 32
&& t->code () == TYPE_CODE_FLT
- && gdbarch_tdep (gdbarch)->have_neon)
+ && tdep->have_neon)
return arm_neon_double_type (gdbarch);
else
return t;
if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
{
- if (!gdbarch_tdep (gdbarch)->have_fpa_registers)
+ if (!tdep->have_fpa_registers)
return builtin_type (gdbarch)->builtin_void;
return arm_ext_type (gdbarch);
static const char *
arm_register_name (struct gdbarch *gdbarch, int i)
{
- const int num_regs = gdbarch_num_regs (gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (gdbarch_tdep (gdbarch)->have_vfp_pseudos
- && i >= num_regs && i < num_regs + 32)
+ if (is_s_pseudo (gdbarch, i))
{
- static const char *const vfp_pseudo_names[] = {
+ static const char *const s_pseudo_names[] = {
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
};
- return vfp_pseudo_names[i - num_regs];
+ return s_pseudo_names[i - tdep->s_pseudo_base];
}
- if (gdbarch_tdep (gdbarch)->have_neon_pseudos
- && i >= num_regs + 32 && i < num_regs + 32 + 16)
+ if (is_q_pseudo (gdbarch, i))
{
- static const char *const neon_pseudo_names[] = {
+ static const char *const q_pseudo_names[] = {
"q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
"q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
};
- return neon_pseudo_names[i - num_regs - 32];
+ return q_pseudo_names[i - tdep->q_pseudo_base];
}
if (i >= ARRAY_SIZE (arm_register_names))
an XML description. */
return "";
+ /* Non-pseudo registers. */
return arm_register_names[i];
}
int offset, double_regnum;
gdb_assert (regnum >= num_regs);
- regnum -= num_regs;
- if (gdbarch_tdep (gdbarch)->have_neon_pseudos && regnum >= 32 && regnum < 48)
- /* Quad-precision register. */
- return arm_neon_quad_read (gdbarch, regcache, regnum - 32, buf);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (is_q_pseudo (gdbarch, regnum))
+ {
+ /* Quad-precision register. */
+ return arm_neon_quad_read (gdbarch, regcache,
+ regnum - tdep->q_pseudo_base, buf);
+ }
else
{
enum register_status status;
+ regnum -= tdep->s_pseudo_base;
/* Single-precision register. */
gdb_assert (regnum < 32);
int offset, double_regnum;
gdb_assert (regnum >= num_regs);
- regnum -= num_regs;
- if (gdbarch_tdep (gdbarch)->have_neon_pseudos && regnum >= 32 && regnum < 48)
- /* Quad-precision register. */
- arm_neon_quad_write (gdbarch, regcache, regnum - 32, buf);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (is_q_pseudo (gdbarch, regnum))
+ {
+ /* Quad-precision register. */
+ arm_neon_quad_write (gdbarch, regcache,
+ regnum - tdep->q_pseudo_base, buf);
+ }
else
{
+ regnum -= tdep->s_pseudo_base;
/* Single-precision register. */
gdb_assert (regnum < 32);
int i;
bool is_m = false;
int vfp_register_count = 0;
- bool have_vfp_pseudos = false, have_neon_pseudos = false;
+ bool have_s_pseudos = false, have_q_pseudos = false;
bool have_wmmx_registers = false;
bool have_neon = false;
bool have_fpa_registers = true;
const struct target_desc *tdesc = info.target_desc;
+ int register_count = ARM_NUM_REGS;
/* If we have an object to base this architecture on, try to determine
its ABI. */
return NULL;
if (tdesc_unnumbered_register (feature, "s0") == 0)
- have_vfp_pseudos = true;
+ have_s_pseudos = true;
vfp_register_count = i;
their type; otherwise (normally) provide them with
the default type. */
if (tdesc_unnumbered_register (feature, "q0") == 0)
- have_neon_pseudos = true;
+ have_q_pseudos = true;
have_neon = true;
}
|| vfp_register_count == 16
|| vfp_register_count == 32);
tdep->vfp_register_count = vfp_register_count;
- tdep->have_vfp_pseudos = have_vfp_pseudos;
- tdep->have_neon_pseudos = have_neon_pseudos;
+ tdep->have_s_pseudos = have_s_pseudos;
+ tdep->have_q_pseudos = have_q_pseudos;
tdep->have_neon = have_neon;
arm_register_g_packet_guesses (gdbarch);
/* Information about registers, etc. */
set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
- set_gdbarch_num_regs (gdbarch, ARM_NUM_REGS);
+ set_gdbarch_num_regs (gdbarch, register_count);
set_gdbarch_register_type (gdbarch, arm_register_type);
set_gdbarch_register_reggroup_p (gdbarch, arm_register_reggroup_p);
set_tdesc_pseudo_register_name (gdbarch, arm_register_name);
tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));
+ register_count = gdbarch_num_regs (gdbarch);
/* Override tdesc_register_type to adjust the types of VFP
registers for NEON. */
set_gdbarch_register_type (gdbarch, arm_register_type);
}
- if (have_vfp_pseudos)
+ /* Initialize the pseudo register data. */
+ if (tdep->have_s_pseudos)
{
- /* NOTE: These are the only pseudo registers used by
- the ARM target at the moment. If more are added, a
- little more care in numbering will be needed. */
+ /* VFP single precision pseudo registers (S0~S31). */
+ tdep->s_pseudo_base = register_count;
+ tdep->s_pseudo_count = 32;
+ int num_pseudos = tdep->s_pseudo_count;
+
+ if (tdep->have_q_pseudos)
+ {
+ /* NEON quad precision pseudo registers (Q0~Q15). */
+ tdep->q_pseudo_base = register_count + num_pseudos;
+ tdep->q_pseudo_count = 16;
+ num_pseudos += tdep->q_pseudo_count;
+ }
- int num_pseudos = 32;
- if (have_neon_pseudos)
- num_pseudos += 16;
set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos);
set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_read);
set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_write);
(int) tdep->have_wmmx_registers);
fprintf_unfiltered (file, _("arm_dump_tdep: vfp_register_count = %i\n"),
(int) tdep->vfp_register_count);
- fprintf_unfiltered (file, _("arm_dump_tdep: have_vfp_pseudos = %i\n"),
- (int) tdep->have_vfp_pseudos);
- fprintf_unfiltered (file, _("arm_dump_tdep: have_neon_pseudos = %i\n"),
- (int) tdep->have_neon_pseudos);
+ fprintf_unfiltered (file, _("arm_dump_tdep: have_s_pseudos = %s\n"),
+ tdep->have_s_pseudos? "true" : "false");
+ fprintf_unfiltered (file, _("arm_dump_tdep: s_pseudo_base = %i\n"),
+ (int) tdep->s_pseudo_base);
+ fprintf_unfiltered (file, _("arm_dump_tdep: s_pseudo_count = %i\n"),
+ (int) tdep->s_pseudo_count);
+ fprintf_unfiltered (file, _("arm_dump_tdep: have_q_pseudos = %s\n"),
+ tdep->have_q_pseudos? "true" : "false");
+ fprintf_unfiltered (file, _("arm_dump_tdep: q_pseudo_base = %i\n"),
+ (int) tdep->q_pseudo_base);
+ fprintf_unfiltered (file, _("arm_dump_tdep: q_pseudo_count = %i\n"),
+ (int) tdep->q_pseudo_count);
fprintf_unfiltered (file, _("arm_dump_tdep: have_neon = %i\n"),
(int) tdep->have_neon);
fprintf_unfiltered (file, _("arm_dump_tdep: Lowest pc = 0x%lx\n"),