public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] gdb/riscv: Apply NaN boxing when writing return values into registers
@ 2020-03-25 11:35 Andrew Burgess
0 siblings, 0 replies; only message in thread
From: Andrew Burgess @ 2020-03-25 11:35 UTC (permalink / raw)
To: gdb-cvs
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=dd8953924b0966e363c27ee38a0663c08f742fa0
commit dd8953924b0966e363c27ee38a0663c08f742fa0
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date: Fri Mar 13 15:50:28 2020 +0000
gdb/riscv: Apply NaN boxing when writing return values into registers
When setting up function parameters we already perform NaN boxing, as
required by the RISC-V ABI, however, we don't do this when writing
values into registers as part of setting up a return value.
This commit moves the NaN boxing code into a small helper function,
and then makes use of this function when setting up function
parameters, and also when setting up return values.
This should resolve this failure:
FAIL: gdb.base/return-nodebug.exp: float: full width of the returned result
gdb/ChangeLog:
PR gdb/25489
* riscv-tdep.c (riscv_arg_info::c_offset): Update comment.
(riscv_regcache_cooked_write): New function.
(riscv_push_dummy_call): Use new function.
(riscv_return_value): Likewise.
Diff:
---
gdb/ChangeLog | 8 +++++++
gdb/riscv-tdep.c | 69 ++++++++++++++++++++++++++++++++------------------------
2 files changed, 48 insertions(+), 29 deletions(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ced1b6d43fa..7d627b55ad4 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2020-03-25 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ PR gdb/25534
+ * riscv-tdep.c (riscv_arg_info::c_offset): Update comment.
+ (riscv_regcache_cooked_write): New function.
+ (riscv_push_dummy_call): Use new function.
+ (riscv_return_value): Likewise.
+
2020-03-24 Simon Marchi <simon.marchi@polymtl.ca>
* fbsd-nat.c (fbsd_nat_target::follow_fork): Change bool to int.
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 2978b9e2d57..0423e6abf30 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -1727,8 +1727,9 @@ struct riscv_arg_info
will go. */
int c_length;
- /* The offset within CONTENTS for this part of the argument. Will
- always be 0 for the first part. For the second part of the
+ /* The offset within CONTENTS for this part of the argument. This can
+ be non-zero even for the first part (the first field of a struct can
+ have a non-zero offset due to padding). For the second part of the
argument, this might be the C_LENGTH value of the first part,
however, if we are passing a structure in two registers, and there's
is padding between the first and second field, then this offset
@@ -2417,6 +2418,26 @@ riscv_print_arg_location (ui_file *stream, struct gdbarch *gdbarch,
}
}
+/* Wrapper around REGCACHE->cooked_write. Places the LEN bytes of DATA
+ into a buffer that is at least as big as the register REGNUM, padding
+ out the DATA with either 0x00, or 0xff. For floating point registers
+ 0xff is used, for everyone else 0x00 is used. */
+
+static void
+riscv_regcache_cooked_write (int regnum, const gdb_byte *data, int len,
+ struct regcache *regcache, int flen)
+{
+ gdb_byte tmp [sizeof (ULONGEST)];
+
+ /* FP values in FP registers must be NaN-boxed. */
+ if (riscv_is_fp_regno_p (regnum) && len < flen)
+ memset (tmp, -1, sizeof (tmp));
+ else
+ memset (tmp, 0, sizeof (tmp));
+ memcpy (tmp, data, len);
+ regcache->cooked_write (regnum, tmp);
+}
+
/* Implement the push dummy call gdbarch callback. */
static CORE_ADDR
@@ -2526,18 +2547,13 @@ riscv_push_dummy_call (struct gdbarch *gdbarch,
{
case riscv_arg_info::location::in_reg:
{
- gdb_byte tmp [sizeof (ULONGEST)];
-
gdb_assert (info->argloc[0].c_length <= info->length);
- /* FP values in FP registers must be NaN-boxed. */
- if (riscv_is_fp_regno_p (info->argloc[0].loc_data.regno)
- && info->argloc[0].c_length < call_info.flen)
- memset (tmp, -1, sizeof (tmp));
- else
- memset (tmp, 0, sizeof (tmp));
- memcpy (tmp, (info->contents + info->argloc[0].c_offset),
- info->argloc[0].c_length);
- regcache->cooked_write (info->argloc[0].loc_data.regno, tmp);
+
+ riscv_regcache_cooked_write (info->argloc[0].loc_data.regno,
+ (info->contents
+ + info->argloc[0].c_offset),
+ info->argloc[0].c_length,
+ regcache, call_info.flen);
second_arg_length =
(((info->argloc[0].c_length + info->argloc[0].c_offset) < info->length)
? info->argloc[1].c_length : 0);
@@ -2569,19 +2585,13 @@ riscv_push_dummy_call (struct gdbarch *gdbarch,
{
case riscv_arg_info::location::in_reg:
{
- gdb_byte tmp [sizeof (ULONGEST)];
-
gdb_assert ((riscv_is_fp_regno_p (info->argloc[1].loc_data.regno)
&& second_arg_length <= call_info.flen)
|| second_arg_length <= call_info.xlen);
- /* FP values in FP registers must be NaN-boxed. */
- if (riscv_is_fp_regno_p (info->argloc[1].loc_data.regno)
- && second_arg_length < call_info.flen)
- memset (tmp, -1, sizeof (tmp));
- else
- memset (tmp, 0, sizeof (tmp));
- memcpy (tmp, second_arg_data, second_arg_length);
- regcache->cooked_write (info->argloc[1].loc_data.regno, tmp);
+ riscv_regcache_cooked_write (info->argloc[1].loc_data.regno,
+ second_arg_data,
+ second_arg_length,
+ regcache, call_info.flen);
}
break;
@@ -2701,9 +2711,9 @@ riscv_return_value (struct gdbarch *gdbarch,
if (writebuf)
{
const gdb_byte *ptr = writebuf + info.argloc[0].c_offset;
- regcache->cooked_write_part (regnum, 0,
+ riscv_regcache_cooked_write (regnum, ptr,
info.argloc[0].c_length,
- ptr);
+ regcache, call_info.flen);
}
/* A return value in register can have a second part in a
@@ -2730,10 +2740,11 @@ riscv_return_value (struct gdbarch *gdbarch,
if (writebuf)
{
- writebuf += info.argloc[1].c_offset;
- regcache->cooked_write_part (regnum, 0,
- info.argloc[1].c_length,
- writebuf);
+ const gdb_byte *ptr
+ = writebuf + info.argloc[1].c_offset;
+ riscv_regcache_cooked_write
+ (regnum, ptr, info.argloc[1].c_length,
+ regcache, call_info.flen);
}
break;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-03-25 11:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-25 11:35 [binutils-gdb] gdb/riscv: Apply NaN boxing when writing return values into registers Andrew Burgess
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).