+2019-01-01 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * arch/riscv.h (struct riscv_gdbarch_features) <hw_float_abi>:
+ Delete.
+ <operator==>: Update with for removed field.
+ <hash>: Likewise.
+ * riscv-tdep.h (struct gdbarch_tdep) <features>: Renamed to...
+ <isa_features>: ...this.
+ <abi_features>: New field.
+ (riscv_isa_flen): Update comment.
+ (riscv_abi_xlen): New declaration.
+ (riscv_abi_flen): New declaration.
+ * riscv-tdep.c (riscv_isa_xlen): Update to get answer from
+ isa_features.
+ (riscv_abi_xlen): New function.
+ (riscv_isa_flen): Update to get answer from isa_features.
+ (riscv_abi_flen): New function.
+ (riscv_has_fp_abi): Update to get answer from abi_features.
+ (riscv_call_info::riscv_call_info): Use abi xlen and flen, not isa
+ xlen and flen.
+ (riscv_call_info) <xlen, flen>: Update comment.
+ (riscv_call_arg_struct): Remove invalid assertions
+ (riscv_features_from_gdbarch_info): Update now hw_float_abi field
+ is removed.
+ (riscv_gdbarch_init): Gather isa features and abi features
+ separately, ensure both match on the gdbarch when reusing an old
+ gdbarch. Relax an error check to allow 32-bit abi float to run on
+ a target with 64-bit float hardware.
+
2019-01-01 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* source.c (search_command_helper): Stop reverse search
int
riscv_isa_xlen (struct gdbarch *gdbarch)
{
- return gdbarch_tdep (gdbarch)->features.xlen;
+ return gdbarch_tdep (gdbarch)->isa_features.xlen;
+}
+
+/* See riscv-tdep.h. */
+
+int
+riscv_abi_xlen (struct gdbarch *gdbarch)
+{
+ return gdbarch_tdep (gdbarch)->abi_features.xlen;
}
/* See riscv-tdep.h. */
int
riscv_isa_flen (struct gdbarch *gdbarch)
{
- return gdbarch_tdep (gdbarch)->features.flen;
+ return gdbarch_tdep (gdbarch)->isa_features.flen;
+}
+
+/* See riscv-tdep.h. */
+
+int
+riscv_abi_flen (struct gdbarch *gdbarch)
+{
+ return gdbarch_tdep (gdbarch)->abi_features.flen;
}
/* Return true if the target for GDBARCH has floating point hardware. */
static bool
riscv_has_fp_abi (struct gdbarch *gdbarch)
{
- return gdbarch_tdep (gdbarch)->features.hw_float_abi;
+ return gdbarch_tdep (gdbarch)->abi_features.flen > 0;
}
/* Return true if REGNO is a floating pointer register. */
: int_regs (RISCV_A0_REGNUM, RISCV_A0_REGNUM + 7),
float_regs (RISCV_FA0_REGNUM, RISCV_FA0_REGNUM + 7)
{
- xlen = riscv_isa_xlen (gdbarch);
- flen = riscv_isa_flen (gdbarch);
+ xlen = riscv_abi_xlen (gdbarch);
+ flen = riscv_abi_flen (gdbarch);
/* Disable use of floating point registers if needed. */
if (!riscv_has_fp_abi (gdbarch))
struct riscv_arg_reg float_regs;
/* The XLEN and FLEN are copied in to this structure for convenience, and
- are just the results of calling RISCV_ISA_XLEN and RISCV_ISA_FLEN. */
+ are just the results of calling RISCV_ABI_XLEN and RISCV_ABI_FLEN. */
int xlen;
int flen;
};
{
int len0, len1, offset;
- gdb_assert (TYPE_LENGTH (ainfo->type)
- <= (cinfo->flen + cinfo->xlen));
-
len0 = TYPE_LENGTH (sinfo.field_type (0));
if (!riscv_assign_reg_location (&ainfo->argloc[0],
&cinfo->float_regs, len0, 0))
{
int len0, len1, offset;
- gdb_assert (TYPE_LENGTH (ainfo->type)
- <= (cinfo->flen + cinfo->xlen));
-
len0 = TYPE_LENGTH (sinfo.field_type (0));
len1 = TYPE_LENGTH (sinfo.field_type (1));
offset = align_up (len0, riscv_type_alignment (sinfo.field_type (1)));
_("unknown ELF header class %d"), eclass);
if (e_flags & EF_RISCV_FLOAT_ABI_DOUBLE)
- {
- features.flen = 8;
- features.hw_float_abi = true;
- }
+ features.flen = 8;
else if (e_flags & EF_RISCV_FLOAT_ABI_SINGLE)
- {
- features.flen = 4;
- features.hw_float_abi = true;
- }
+ features.flen = 4;
}
else
{
/* Have a look at what the supplied (if any) bfd object requires of the
target, then check that this matches with what the target is
providing. */
- struct riscv_gdbarch_features info_features
+ struct riscv_gdbarch_features abi_features
= riscv_features_from_gdbarch_info (info);
- if (info_features.xlen != 0 && info_features.xlen != features.xlen)
+ /* In theory a binary compiled for RV32 could run on an RV64 target,
+ however, this has not been tested in GDB yet, so for now we require
+ that the requested xlen match the targets xlen. */
+ if (abi_features.xlen != 0 && abi_features.xlen != features.xlen)
error (_("bfd requires xlen %d, but target has xlen %d"),
- info_features.xlen, features.xlen);
- if (info_features.flen != 0 && info_features.flen != features.flen)
+ abi_features.xlen, features.xlen);
+ /* We do support running binaries compiled for 32-bit float on targets
+ with 64-bit float, so we only complain if the binary requires more
+ than the target has available. */
+ if (abi_features.flen > features.flen)
error (_("bfd requires flen %d, but target has flen %d"),
- info_features.flen, features.flen);
-
- /* If the xlen from INFO_FEATURES is 0 then this indicates either there
- is no bfd object, or nothing useful could be extracted from it, in
- this case we enable hardware float abi if the target has floating
- point registers.
+ abi_features.flen, features.flen);
- If the xlen from INFO_FEATURES is not 0, and the flen in
- INFO_FEATURES is also not 0, then this indicates that the supplied
- bfd does require hardware floating point abi. */
- if (info_features.xlen == 0 || info_features.flen != 0)
- features.hw_float_abi = (features.flen > 0);
+ /* If the ABI_FEATURES xlen is 0 then this indicates we got no useful abi
+ features from the INFO object. In this case we assume that the xlen
+ abi matches the hardware. */
+ if (abi_features.xlen == 0)
+ abi_features.xlen = features.xlen;
/* Find a candidate among the list of pre-declared architectures. */
for (arches = gdbarch_list_lookup_by_info (arches, &info);
gdbarch. */
struct gdbarch_tdep *other_tdep = gdbarch_tdep (arches->gdbarch);
- if (other_tdep->features != features)
+ if (other_tdep->isa_features != features
+ || other_tdep->abi_features != abi_features)
continue;
break;
/* None found, so create a new architecture from the information provided. */
tdep = new (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
- tdep->features = features;
+ tdep->isa_features = features;
+ tdep->abi_features = abi_features;
/* Target data types. */
set_gdbarch_short_bit (gdbarch, 16);
/* RISC-V specific per-architecture information. */
struct gdbarch_tdep
{
- /* Features about the target that impact how the gdbarch is configured.
- Two gdbarch instances are compatible only if this field matches. */
- struct riscv_gdbarch_features features;
+ /* Features about the target hardware that impact how the gdbarch is
+ configured. Two gdbarch instances are compatible only if this field
+ matches. */
+ struct riscv_gdbarch_features isa_features;
+
+ /* Features about the abi that impact how the gdbarch is configured. Two
+ gdbarch instances are compatible only if this field matches. */
+ struct riscv_gdbarch_features abi_features;
/* ISA-specific data types. */
struct type *riscv_fpreg_d_type = nullptr;
RV128. */
extern int riscv_isa_xlen (struct gdbarch *gdbarch);
-/* Return the width in bytes of the floating point registers for GDBARCH.
- If this architecture has no floating point registers, then return 0.
- Possible values are 4, 8, or 16 for depending on which of single, double
- or quad floating point support is available. */
+/* Return the width in bytes of the hardware floating point registers for
+ GDBARCH. If this architecture has no floating point registers, then
+ return 0. Possible values are 4, 8, or 16 for depending on which of
+ single, double or quad floating point support is available. */
extern int riscv_isa_flen (struct gdbarch *gdbarch);
+/* Return the width in bytes of the general purpose register abi for
+ GDBARCH. This can be equal to, or less than RISCV_ISA_XLEN and reflects
+ how the binary was compiled rather than the hardware that is available.
+ It is possible that a binary compiled for RV32 is being run on an RV64
+ target, in which case the isa xlen is 8-bytes, and the abi xlen is
+ 4-bytes. This will impact how inferior functions are called. */
+extern int riscv_abi_xlen (struct gdbarch *gdbarch);
+
+/* Return the width in bytes of the floating point register abi for
+ GDBARCH. This reflects how the binary was compiled rather than the
+ hardware that is available. It is possible that a binary is compiled
+ for single precision floating point, and then run on a target with
+ double precision floating point. A return value of 0 indicates that no
+ floating point abi is in use (floating point arguments will be passed
+ in integer registers) other possible return value are 4, 8, or 16 as
+ with RISCV_ISA_FLEN. */
+extern int riscv_abi_flen (struct gdbarch *gdbarch);
+
/* Single step based on where the current instruction will take us. */
extern std::vector<CORE_ADDR> riscv_software_single_step
(struct regcache *regcache);