From: Vladimir Prus <vladimir@codesourcery.com>
To: Mark Kettenis <mark.kettenis@xs4all.nl>
Cc: gdb-patches@sources.redhat.com
Subject: Re: m68k-elf return value registers
Date: Tue, 26 Apr 2011 11:50:00 -0000 [thread overview]
Message-ID: <201104261550.27639.vladimir@codesourcery.com> (raw)
In-Reply-To: <201101251949.15840.vladimir@codesourcery.com>
[-- Attachment #1: Type: Text/Plain, Size: 293 bytes --]
On Tuesday, January 25, 2011 19:49:15 Vladimir Prus wrote:
> How about this split:
>
> - Register used to return structures
> - Logic used to decide whether a structure is returned in register
Here's a patch for this aspect.
- Volodya
--
Vladimir Prus
Mentor Graphics
+7 (812) 677-68-40
[-- Attachment #2: is_using_register_for_struct_return.diff --]
[-- Type: text/x-patch, Size: 4279 bytes --]
commit 46907f38a4f2d3fadf755aad647fb089d32ad6cb
Author: Vladimir Prus <vladimir@codesourcery.com>
Date: Tue Apr 26 15:47:50 2011 +0400
Adjust "is register used for struct returns" logic to what GCC does.
* m68k-tdep.c (m68k_reg_struct_return_r): New, broken out of ...
(m68k_reg_struct_return_p): ... here. Implement gcc's structure
mode algorithm.
(m68k_svr4_return_value): Adjust to gcc behaviour.
diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c
index c6ae36d..736bf5b 100644
--- a/gdb/m68k-tdep.c
+++ b/gdb/m68k-tdep.c
@@ -378,6 +378,70 @@ m68k_svr4_store_return_value (struct type *type, struct regcache *regcache,
/* Return non-zero if TYPE, which is assumed to be a structure or
union type, should be returned in registers for architecture
+ GDBARCH.
+
+ Unfortunately GCC incorrectly implements this optimization. Rather
+ than simply return all small structs, or even just those of size
+ 2^N, it uses the mode of the structure to determine this. BLKmode
+ structs will be returned by memory and QI,HI,SI,DI,SF&DF mode
+ structs will be returned by register. For m68k a struct is BLKmode
+ unless it's size is 2^N and the mode for that size does not need a
+ greater alignment than the structure itself. This is horrible. */
+
+
+static int
+m68k_reg_struct_return_r (struct type *type, int *align_p)
+{
+ enum type_code code = TYPE_CODE (type);
+ int len = TYPE_LENGTH (type);
+ int field_align = 1;
+ int my_align = len > 2 ? 2 : len;
+ int ix;
+
+ if (code != TYPE_CODE_STRUCT && code != TYPE_CODE_UNION)
+ {
+ if (align_p && my_align > *align_p)
+ *align_p = my_align;
+ return 1;
+ }
+
+ if ((len & -len) != len)
+ /* Length is not 2^n. */
+ return 0;
+
+ for (ix = 0; ix != TYPE_NFIELDS (type); ix++)
+ {
+ struct type *field_type;
+ int field_len;
+
+ if (field_is_static (&TYPE_FIELD (type, ix)))
+ /* Skip static fields. */
+ continue;
+
+ field_type = TYPE_FIELD_TYPE (type, ix);
+ field_type = check_typedef (field_type);
+ field_len = TYPE_LENGTH (field_type);
+
+ /* Look through arrays. */
+ while (TYPE_CODE (field_type) == TYPE_CODE_ARRAY)
+ {
+ field_type = TYPE_TARGET_TYPE (field_type);
+ field_type = check_typedef (field_type);
+ field_len = TYPE_LENGTH (field_type);
+ }
+
+ if (!m68k_reg_struct_return_r (field_type, &field_align))
+ return 0;
+ }
+
+ if (align_p && field_align > *align_p)
+ *align_p = field_align;
+
+ return align_p || my_align <= field_align;
+}
+
+/* Return non-zero if TYPE, which is assumed to be a structure or
+ union type, should be returned in registers for architecture
GDBARCH. */
static int
@@ -392,7 +456,11 @@ m68k_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
if (tdep->struct_return == pcc_struct_return)
return 0;
- return (len == 1 || len == 2 || len == 4 || len == 8);
+ if (len > 8)
+ /* Length is too big. */
+ return 0;
+
+ return m68k_reg_struct_return_r (type, NULL);
}
/* Determine, for architecture GDBARCH, how a return value of TYPE
@@ -446,25 +514,11 @@ m68k_svr4_return_value (struct gdbarch *gdbarch, struct type *func_type,
if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
&& !m68k_reg_struct_return_p (gdbarch, type))
{
- /* The System V ABI says that:
-
- "A function returning a structure or union also sets %a0 to
- the value it finds in %a0. Thus when the caller receives
- control again, the address of the returned object resides in
- register %a0."
-
- So the ABI guarantees that we can always find the return
- value just after the function has returned. */
-
- if (readbuf)
- {
- ULONGEST addr;
-
- regcache_raw_read_unsigned (regcache, M68K_A0_REGNUM, &addr);
- read_memory (addr, readbuf, TYPE_LENGTH (type));
- }
-
- return RETURN_VALUE_ABI_RETURNS_ADDRESS;
+ /* Although they SYSV ABI specifies that a function returning a
+ structure this way should preserve %a0, GCC doesn't do that.
+ Furthermore there's no point changeing GCC to make it do it,
+ as that would just be bloat. */
+ return RETURN_VALUE_STRUCT_CONVENTION;
}
/* This special case is for structures consisting of a single
next prev parent reply other threads:[~2011-04-26 11:50 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-13 23:04 Vladimir Prus
2011-01-14 11:00 ` Mark Kettenis
2011-01-25 17:01 ` Vladimir Prus
2011-04-26 11:37 ` Vladimir Prus
2011-06-11 18:50 ` Vladimir Prus
2011-04-26 11:50 ` Vladimir Prus [this message]
2011-04-26 11:58 ` Vladimir Prus
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=201104261550.27639.vladimir@codesourcery.com \
--to=vladimir@codesourcery.com \
--cc=gdb-patches@sources.redhat.com \
--cc=mark.kettenis@xs4all.nl \
/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