From: Andreas Arnez <arnez@linux.vnet.ibm.com>
To: gdb-patches@sourceware.org
Cc: Sergio Durigan Junior <sergiodj@redhat.com>,
Ulrich Weigand <uweigand@de.ibm.com>
Subject: [PATCH 3/4] S390: Re-arrange implementation of s390_return_value
Date: Wed, 22 Apr 2015 17:51:00 -0000 [thread overview]
Message-ID: <878udk830t.fsf@br87z6lw.de.ibm.com> (raw)
In-Reply-To: <1429724743-4603-1-git-send-email-arnez@linux.vnet.ibm.com> (Andreas Arnez's message of "Wed, 22 Apr 2015 19:44:59 +0200")
Move related logic in the implementation of s390_return_value closer
together. This makes it easier to read and extend.
gdb/ChangeLog:
* s390-linux-tdep.c (s390_return_value_convention): Remove
function. Inline its logic...
(s390_return_value): ...here. Instead, move the handling of the
"register" return value convention...
(s390_register_return_value): ...here. New function.
---
gdb/s390-linux-tdep.c | 158 +++++++++++++++++++++++---------------------------
1 file changed, 73 insertions(+), 85 deletions(-)
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index 3b7e4b6..bb9b28e 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -2708,110 +2708,98 @@ s390_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
}
-/* Function return value access. */
+/* Helper for s390_return_value: Set or retrieve a function return
+ value if it resides in a register. */
-static enum return_value_convention
-s390_return_value_convention (struct gdbarch *gdbarch, struct type *type)
+static void
+s390_register_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache,
+ gdb_byte *out, const gdb_byte *in)
{
- if (TYPE_LENGTH (type) > 8)
- return RETURN_VALUE_STRUCT_CONVENTION;
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ int word_size = gdbarch_ptr_bit (gdbarch) / 8;
+ int length = TYPE_LENGTH (type);
+ int code = TYPE_CODE (type);
- switch (TYPE_CODE (type))
+ if (code == TYPE_CODE_FLT || code == TYPE_CODE_DECFLOAT)
{
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_UNION:
- case TYPE_CODE_ARRAY:
- case TYPE_CODE_COMPLEX:
- return RETURN_VALUE_STRUCT_CONVENTION;
-
- default:
- return RETURN_VALUE_REGISTER_CONVENTION;
+ /* Float-like value: left-aligned in f0. */
+ if (in != NULL)
+ regcache_cooked_write_part (regcache, S390_F0_REGNUM,
+ 0, length, in);
+ else
+ regcache_cooked_read_part (regcache, S390_F0_REGNUM,
+ 0, length, out);
+ }
+ else if (length <= word_size)
+ {
+ /* Integer: zero- or sign-extended in r2. */
+ if (out != NULL)
+ regcache_cooked_read_part (regcache, S390_R2_REGNUM,
+ word_size - length, length, out);
+ else if (TYPE_UNSIGNED (type))
+ regcache_cooked_write_unsigned
+ (regcache, S390_R2_REGNUM,
+ extract_unsigned_integer (in, length, byte_order));
+ else
+ regcache_cooked_write_signed
+ (regcache, S390_R2_REGNUM,
+ extract_signed_integer (in, length, byte_order));
+ }
+ else if (length == 2 * word_size)
+ {
+ /* Double word: in r2 and r3. */
+ if (in != NULL)
+ {
+ regcache_cooked_write (regcache, S390_R2_REGNUM, in);
+ regcache_cooked_write (regcache, S390_R3_REGNUM,
+ in + word_size);
+ }
+ else
+ {
+ regcache_cooked_read (regcache, S390_R2_REGNUM, out);
+ regcache_cooked_read (regcache, S390_R3_REGNUM,
+ out + word_size);
+ }
}
+ else
+ internal_error (__FILE__, __LINE__, _("invalid return type"));
}
+
+/* Implement the 'return_value' gdbarch method. */
+
static enum return_value_convention
s390_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache,
gdb_byte *out, const gdb_byte *in)
{
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int word_size = gdbarch_ptr_bit (gdbarch) / 8;
enum return_value_convention rvc;
- int length;
type = check_typedef (type);
- rvc = s390_return_value_convention (gdbarch, type);
- length = TYPE_LENGTH (type);
- if (in)
+ switch (TYPE_CODE (type))
{
- switch (rvc)
- {
- case RETURN_VALUE_REGISTER_CONVENTION:
- if (TYPE_CODE (type) == TYPE_CODE_FLT
- || TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
- {
- /* When we store a single-precision value in an FP register,
- it occupies the leftmost bits. */
- regcache_cooked_write_part (regcache, S390_F0_REGNUM,
- 0, length, in);
- }
- else if (length <= word_size)
- {
- /* Integer arguments are always extended to word size. */
- if (TYPE_UNSIGNED (type))
- regcache_cooked_write_unsigned (regcache, S390_R2_REGNUM,
- extract_unsigned_integer (in, length, byte_order));
- else
- regcache_cooked_write_signed (regcache, S390_R2_REGNUM,
- extract_signed_integer (in, length, byte_order));
- }
- else if (length == 2*word_size)
- {
- regcache_cooked_write (regcache, S390_R2_REGNUM, in);
- regcache_cooked_write (regcache, S390_R3_REGNUM, in + word_size);
- }
- else
- internal_error (__FILE__, __LINE__, _("invalid return type"));
- break;
-
- case RETURN_VALUE_STRUCT_CONVENTION:
- error (_("Cannot set function return value."));
- break;
- }
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_ARRAY:
+ case TYPE_CODE_COMPLEX:
+ rvc = RETURN_VALUE_STRUCT_CONVENTION;
+ break;
+ default:
+ rvc = TYPE_LENGTH (type) <= 8
+ ? RETURN_VALUE_REGISTER_CONVENTION
+ : RETURN_VALUE_STRUCT_CONVENTION;
}
- else if (out)
- {
- switch (rvc)
- {
- case RETURN_VALUE_REGISTER_CONVENTION:
- if (TYPE_CODE (type) == TYPE_CODE_FLT
- || TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
- {
- /* When we store a single-precision value in an FP register,
- it occupies the leftmost bits. */
- regcache_cooked_read_part (regcache, S390_F0_REGNUM,
- 0, length, out);
- }
- else if (length <= word_size)
- {
- /* Integer arguments occupy the rightmost bits. */
- regcache_cooked_read_part (regcache, S390_R2_REGNUM,
- word_size - length, length, out);
- }
- else if (length == 2*word_size)
- {
- regcache_cooked_read (regcache, S390_R2_REGNUM, out);
- regcache_cooked_read (regcache, S390_R3_REGNUM, out + word_size);
- }
- else
- internal_error (__FILE__, __LINE__, _("invalid return type"));
- break;
- case RETURN_VALUE_STRUCT_CONVENTION:
- error (_("Function return value unknown."));
- break;
- }
+ if (in != NULL || out != NULL)
+ {
+ if (rvc == RETURN_VALUE_REGISTER_CONVENTION)
+ s390_register_return_value (gdbarch, type, regcache, out, in);
+ else if (in != NULL)
+ error (_("Cannot set function return value."));
+ else
+ error (_("Function return value unknown."));
}
return rvc;
--
1.9.3
next prev parent reply other threads:[~2015-04-22 17:51 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-22 17:45 [PATCH 0/4] S390: Vector ABI support Andreas Arnez
2015-04-22 17:49 ` [PATCH 1/4] S390: For zero, let is_power_of_two() return false Andreas Arnez
2015-04-23 16:02 ` Ulrich Weigand
2015-04-22 17:51 ` Andreas Arnez [this message]
2015-04-23 16:03 ` [PATCH 3/4] S390: Re-arrange implementation of s390_return_value Ulrich Weigand
2015-04-22 17:51 ` [PATCH 2/4] S390: Restructure s390_push_dummy_call Andreas Arnez
2015-04-23 16:03 ` Ulrich Weigand
2015-04-22 17:52 ` [PATCH 4/4] S390: Vector ABI support Andreas Arnez
2015-04-22 17:58 ` Andreas Arnez
2015-04-23 16:07 ` Ulrich Weigand
2015-04-24 14:46 ` Andreas Arnez
2015-04-23 16:47 ` Eli Zaretskii
2015-04-27 9:41 ` [PATCH 0/4] " Andreas Krebbel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=878udk830t.fsf@br87z6lw.de.ibm.com \
--to=arnez@linux.vnet.ibm.com \
--cc=gdb-patches@sourceware.org \
--cc=sergiodj@redhat.com \
--cc=uweigand@de.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox