Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
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

  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