public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Alan Hayward <alan.hayward@arm.com>
To: gdb-patches@sourceware.org
Cc: nd@arm.com,	Alan Hayward <alan.hayward@arm.com>
Subject: [PATCH 3/4] Aarch64: Float register detection for return values.
Date: Mon, 20 Aug 2018 09:30:00 -0000	[thread overview]
Message-ID: <20180820092933.83224-4-alan.hayward@arm.com> (raw)
In-Reply-To: <20180820092933.83224-1-alan.hayward@arm.com>

Use aapcs_is_vfp_call_or_return_candidate to detect float register
args.

Remove the no longer used is_hfa_or_hva().

2018-08-20  Alan Hayward  <alan.hayward@arm.com>

	PR gdb/22943:
	* aarch64-tdep.c (is_hfa_or_hva): Remove function.
	(aarch64_extract_return_value): Use
	aapcs_is_vfp_call_or_return_candidate.
	(aarch64_return_in_memory): Likewise.
	(aarch64_store_return_value): Likewise.
---
 gdb/aarch64-tdep.c | 200 +++++++++++++----------------------------------------
 1 file changed, 47 insertions(+), 153 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 45dde8a37e..7ff97f9078 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -1151,68 +1151,6 @@ aarch64_type_align (struct type *t)
     }
 }
 
-/* Return 1 if *TY is a homogeneous floating-point aggregate or
-   homogeneous short-vector aggregate as defined in the AAPCS64 ABI
-   document; otherwise return 0.  */
-
-static int
-is_hfa_or_hva (struct type *ty)
-{
-  switch (TYPE_CODE (ty))
-    {
-    case TYPE_CODE_ARRAY:
-      {
-	struct type *target_ty = TYPE_TARGET_TYPE (ty);
-
-	if (TYPE_VECTOR (ty))
-	  return 0;
-
-	if (TYPE_LENGTH (ty) <= 4 /* HFA or HVA has at most 4 members.  */
-	    && (TYPE_CODE (target_ty) == TYPE_CODE_FLT /* HFA */
-		|| (TYPE_CODE (target_ty) == TYPE_CODE_ARRAY /* HVA */
-		    && TYPE_VECTOR (target_ty))))
-	  return 1;
-	break;
-      }
-
-    case TYPE_CODE_UNION:
-    case TYPE_CODE_STRUCT:
-      {
-	/* HFA or HVA has at most four members.  */
-	if (TYPE_NFIELDS (ty) > 0 && TYPE_NFIELDS (ty) <= 4)
-	  {
-	    struct type *member0_type;
-
-	    member0_type = check_typedef (TYPE_FIELD_TYPE (ty, 0));
-	    if (TYPE_CODE (member0_type) == TYPE_CODE_FLT
-		|| (TYPE_CODE (member0_type) == TYPE_CODE_ARRAY
-		    && TYPE_VECTOR (member0_type)))
-	      {
-		int i;
-
-		for (i = 0; i < TYPE_NFIELDS (ty); i++)
-		  {
-		    struct type *member1_type;
-
-		    member1_type = check_typedef (TYPE_FIELD_TYPE (ty, i));
-		    if (TYPE_CODE (member0_type) != TYPE_CODE (member1_type)
-			|| (TYPE_LENGTH (member0_type)
-			    != TYPE_LENGTH (member1_type)))
-		      return 0;
-		  }
-		return 1;
-	      }
-	  }
-	return 0;
-      }
-
-    default:
-      break;
-    }
-
-  return 0;
-}
-
 /* Worker function for aapcs_is_vfp_call_or_return_candidate.
 
    Return the number of register required, or -1 on failure.
@@ -1988,14 +1926,30 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
 {
   struct gdbarch *gdbarch = regs->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  int elements;
+  struct type *fundamental_type;
 
-  if (TYPE_CODE (type) == TYPE_CODE_FLT)
+  if (aapcs_is_vfp_call_or_return_candidate (type, &elements,
+					     &fundamental_type))
     {
-      bfd_byte buf[V_REGISTER_SIZE];
-      int len = TYPE_LENGTH (type);
+      int len = TYPE_LENGTH (fundamental_type);
 
-      regs->cooked_read (AARCH64_V0_REGNUM, buf);
-      memcpy (valbuf, buf, len);
+      for (int i = 0; i < elements; i++)
+	{
+	  int regno = AARCH64_V0_REGNUM + i;
+	  bfd_byte buf[V_REGISTER_SIZE];
+
+	  if (aarch64_debug)
+	    {
+	      debug_printf ("read HFA or HVA return value element %d from %s\n",
+			    i + 1,
+			    gdbarch_register_name (gdbarch, regno));
+	    }
+	  regs->cooked_read (regno, buf);
+
+	  memcpy (valbuf, buf, len);
+	  valbuf += len;
+	}
     }
   else if (TYPE_CODE (type) == TYPE_CODE_INT
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
@@ -2023,53 +1977,6 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs,
 	  valbuf += X_REGISTER_SIZE;
 	}
     }
-  else if (TYPE_CODE (type) == TYPE_CODE_COMPLEX)
-    {
-      int regno = AARCH64_V0_REGNUM;
-      bfd_byte buf[V_REGISTER_SIZE];
-      struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
-      int len = TYPE_LENGTH (target_type);
-
-      regs->cooked_read (regno, buf);
-      memcpy (valbuf, buf, len);
-      valbuf += len;
-      regs->cooked_read (regno + 1, buf);
-      memcpy (valbuf, buf, len);
-      valbuf += len;
-    }
-  else if (is_hfa_or_hva (type))
-    {
-      int elements = TYPE_NFIELDS (type);
-      struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0));
-      int len = TYPE_LENGTH (member_type);
-      int i;
-
-      for (i = 0; i < elements; i++)
-	{
-	  int regno = AARCH64_V0_REGNUM + i;
-	  bfd_byte buf[V_REGISTER_SIZE];
-
-	  if (aarch64_debug)
-	    {
-	      debug_printf ("read HFA or HVA return value element %d from %s\n",
-			    i + 1,
-			    gdbarch_register_name (gdbarch, regno));
-	    }
-	  regs->cooked_read (regno, buf);
-
-	  memcpy (valbuf, buf, len);
-	  valbuf += len;
-	}
-    }
-  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
-	   && (TYPE_LENGTH (type) == 16 || TYPE_LENGTH (type) == 8))
-    {
-      /* Short vector is returned in V register.  */
-      gdb_byte buf[V_REGISTER_SIZE];
-
-      regs->cooked_read (AARCH64_V0_REGNUM, buf);
-      memcpy (valbuf, buf, TYPE_LENGTH (type));
-    }
   else
     {
       /* For a structure or union the behaviour is as if the value had
@@ -2098,8 +2005,11 @@ static int
 aarch64_return_in_memory (struct gdbarch *gdbarch, struct type *type)
 {
   type = check_typedef (type);
+  int elements;
+  struct type *fundamental_type;
 
-  if (is_hfa_or_hva (type))
+  if (aapcs_is_vfp_call_or_return_candidate (type, &elements,
+					     &fundamental_type))
     {
       /* v0-v7 are used to return values and one register is allocated
 	 for one member.  However, HFA or HVA has at most four members.  */
@@ -2126,14 +2036,31 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
 {
   struct gdbarch *gdbarch = regs->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  int elements;
+  struct type *fundamental_type;
 
-  if (TYPE_CODE (type) == TYPE_CODE_FLT)
+  if (aapcs_is_vfp_call_or_return_candidate (type, &elements,
+					     &fundamental_type))
     {
-      bfd_byte buf[V_REGISTER_SIZE];
-      int len = TYPE_LENGTH (type);
+      int len = TYPE_LENGTH (fundamental_type);
+
+      for (int i = 0; i < elements; i++)
+	{
+	  int regno = AARCH64_V0_REGNUM + i;
+	  bfd_byte tmpbuf[V_REGISTER_SIZE];
+
+	  if (aarch64_debug)
+	    {
+	      debug_printf ("write HFA or HVA return value element %d to %s\n",
+			    i + 1,
+			    gdbarch_register_name (gdbarch, regno));
+	    }
 
-      memcpy (buf, valbuf, len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len);
-      regs->cooked_write (AARCH64_V0_REGNUM, buf);
+	  memcpy (tmpbuf, valbuf,
+		  len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len);
+	  regs->cooked_write (regno, tmpbuf);
+	  valbuf += len;
+	}
     }
   else if (TYPE_CODE (type) == TYPE_CODE_INT
 	   || TYPE_CODE (type) == TYPE_CODE_CHAR
@@ -2168,39 +2095,6 @@ aarch64_store_return_value (struct type *type, struct regcache *regs,
 	    }
 	}
     }
-  else if (is_hfa_or_hva (type))
-    {
-      int elements = TYPE_NFIELDS (type);
-      struct type *member_type = check_typedef (TYPE_FIELD_TYPE (type, 0));
-      int len = TYPE_LENGTH (member_type);
-      int i;
-
-      for (i = 0; i < elements; i++)
-	{
-	  int regno = AARCH64_V0_REGNUM + i;
-	  bfd_byte tmpbuf[V_REGISTER_SIZE];
-
-	  if (aarch64_debug)
-	    {
-	      debug_printf ("write HFA or HVA return value element %d to %s\n",
-			    i + 1,
-			    gdbarch_register_name (gdbarch, regno));
-	    }
-
-	  memcpy (tmpbuf, valbuf, len);
-	  regs->cooked_write (regno, tmpbuf);
-	  valbuf += len;
-	}
-    }
-  else if (TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
-	   && (TYPE_LENGTH (type) == 8 || TYPE_LENGTH (type) == 16))
-    {
-      /* Short vector.  */
-      gdb_byte buf[V_REGISTER_SIZE];
-
-      memcpy (buf, valbuf, TYPE_LENGTH (type));
-      regs->cooked_write (AARCH64_V0_REGNUM, buf);
-    }
   else
     {
       /* For a structure or union the behaviour is as if the value had
-- 
2.15.2 (Apple Git-101.1)

  parent reply	other threads:[~2018-08-20  9:30 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-20  9:29 [PATCH 0/4] Aarch64: Correctly support args passed in float registers Alan Hayward
2018-08-20  9:29 ` [PATCH 1/4] Aarch64: Func to detect args passed in float regs Alan Hayward
2018-08-28 15:43   ` Simon Marchi
2018-08-28 15:49     ` Alan Hayward
2018-08-28 16:00       ` Simon Marchi
2018-08-20  9:30 ` [PATCH 4/4] infcall-nested-structs: Test up to five fields Alan Hayward
2018-08-28 16:52   ` Simon Marchi
2018-08-20  9:30 ` [PATCH 2/4] Aarch64: Float register detection for _push_dummy_call Alan Hayward
2018-08-28 15:58   ` Simon Marchi
2018-08-20  9:30 ` Alan Hayward [this message]
2018-08-28 16:03   ` [PATCH 3/4] Aarch64: Float register detection for return values Simon Marchi
2018-08-28  9:39 ` [Ping][PATCH 0/4] Aarch64: Correctly support args passed in float registers Alan Hayward

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=20180820092933.83224-4-alan.hayward@arm.com \
    --to=alan.hayward@arm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=nd@arm.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).