public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Refactor arm_return_in_memory
  2015-11-11 10:54 [PATCH 0/2] PR 19051: support of inferior call with gnu vector support on ARM Yao Qi
@ 2015-11-11 10:54 ` Yao Qi
  2015-11-11 10:54 ` [PATCH 2/2] PR 19051: support of inferior call with gnu vector support on ARM Yao Qi
  2015-11-13 15:13 ` [PATCH 0/2] " Yao Qi
  2 siblings, 0 replies; 4+ messages in thread
From: Yao Qi @ 2015-11-11 10:54 UTC (permalink / raw)
  To: gdb-patches

Current arm_return_in_memory isn't friendly to adding new things in it.
Moreover, a lot of stuff are about APCS, which is not used nowadays (AAPCS
is being used).  This patch is to refactor arm_return_in_memory, so that
some code can be shared for both APCS and AAPCS at the beginning of
arm_return_in_memory, and then each ABI (APCS and AAPCS) are processed
separately.

gdb:

2015-11-11  Yao Qi  <yao.qi@linaro.org>

	* arm-tdep.c (arm_return_in_memory): Rewrite it.
	(arm_return_value): Call arm_return_in_memory for
	TYPE_CODE_COMPLEX.
---
 gdb/arm-tdep.c | 162 ++++++++++++++++++++++++++++++---------------------------
 1 file changed, 84 insertions(+), 78 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 4f8c7f2..f52f03a 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -8991,99 +8991,106 @@ arm_extract_return_value (struct type *type, struct regcache *regs,
 static int
 arm_return_in_memory (struct gdbarch *gdbarch, struct type *type)
 {
-  int nRc;
   enum type_code code;
 
   type = check_typedef (type);
 
-  /* In the ARM ABI, "integer" like aggregate types are returned in
-     registers.  For an aggregate type to be integer like, its size
-     must be less than or equal to INT_REGISTER_SIZE and the
-     offset of each addressable subfield must be zero.  Note that bit
-     fields are not addressable, and all addressable subfields of
-     unions always start at offset zero.
-
-     This function is based on the behaviour of GCC 2.95.1.
-     See: gcc/arm.c: arm_return_in_memory() for details.
-
-     Note: All versions of GCC before GCC 2.95.2 do not set up the
-     parameters correctly for a function returning the following
-     structure: struct { float f;}; This should be returned in memory,
-     not a register.  Richard Earnshaw sent me a patch, but I do not
-     know of any way to detect if a function like the above has been
-     compiled with the correct calling convention.  */
+  /* Simple, non-aggregate types (ie not including vectors and
+     complex) are always returned in a register (or registers).  */
+  code = TYPE_CODE (type);
+  if (TYPE_CODE_STRUCT != code && TYPE_CODE_UNION != code
+      && TYPE_CODE_ARRAY != code && TYPE_CODE_COMPLEX != code)
+    return 0;
 
-  /* All aggregate types that won't fit in a register must be returned
-     in memory.  */
-  if (TYPE_LENGTH (type) > INT_REGISTER_SIZE)
+  if (gdbarch_tdep (gdbarch)->arm_abi != ARM_ABI_APCS)
     {
+      /* The AAPCS says all aggregates not larger than a word are returned
+	 in a register.  */
+      if (TYPE_LENGTH (type) <= INT_REGISTER_SIZE)
+	return 0;
+
       return 1;
     }
+  else
+    {
+      int nRc;
 
-  /* The AAPCS says all aggregates not larger than a word are returned
-     in a register.  */
-  if (gdbarch_tdep (gdbarch)->arm_abi != ARM_ABI_APCS)
-    return 0;
+      /* All aggregate types that won't fit in a register must be returned
+	 in memory.  */
+      if (TYPE_LENGTH (type) > INT_REGISTER_SIZE)
+	return 1;
 
-  /* The only aggregate types that can be returned in a register are
-     structs and unions.  Arrays must be returned in memory.  */
-  code = TYPE_CODE (type);
-  if ((TYPE_CODE_STRUCT != code) && (TYPE_CODE_UNION != code))
-    {
-      return 1;
-    }
+      /* In the ARM ABI, "integer" like aggregate types are returned in
+	 registers.  For an aggregate type to be integer like, its size
+	 must be less than or equal to INT_REGISTER_SIZE and the
+	 offset of each addressable subfield must be zero.  Note that bit
+	 fields are not addressable, and all addressable subfields of
+	 unions always start at offset zero.
 
-  /* Assume all other aggregate types can be returned in a register.
-     Run a check for structures, unions and arrays.  */
-  nRc = 0;
+	 This function is based on the behaviour of GCC 2.95.1.
+	 See: gcc/arm.c: arm_return_in_memory() for details.
 
-  if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code))
-    {
-      int i;
-      /* Need to check if this struct/union is "integer" like.  For
-         this to be true, its size must be less than or equal to
-         INT_REGISTER_SIZE and the offset of each addressable
-         subfield must be zero.  Note that bit fields are not
-         addressable, and unions always start at offset zero.  If any
-         of the subfields is a floating point type, the struct/union
-         cannot be an integer type.  */
-
-      /* For each field in the object, check:
-         1) Is it FP? --> yes, nRc = 1;
-         2) Is it addressable (bitpos != 0) and
-         not packed (bitsize == 0)?
-         --> yes, nRc = 1  
-       */
-
-      for (i = 0; i < TYPE_NFIELDS (type); i++)
-	{
-	  enum type_code field_type_code;
-	  field_type_code = TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type,
-								       i)));
-
-	  /* Is it a floating point type field?  */
-	  if (field_type_code == TYPE_CODE_FLT)
-	    {
-	      nRc = 1;
-	      break;
-	    }
+	 Note: All versions of GCC before GCC 2.95.2 do not set up the
+	 parameters correctly for a function returning the following
+	 structure: struct { float f;}; This should be returned in memory,
+	 not a register.  Richard Earnshaw sent me a patch, but I do not
+	 know of any way to detect if a function like the above has been
+	 compiled with the correct calling convention.  */
+
+      /* Assume all other aggregate types can be returned in a register.
+	 Run a check for structures, unions and arrays.  */
+      nRc = 0;
 
-	  /* If bitpos != 0, then we have to care about it.  */
-	  if (TYPE_FIELD_BITPOS (type, i) != 0)
+      if ((TYPE_CODE_STRUCT == code) || (TYPE_CODE_UNION == code))
+	{
+	  int i;
+	  /* Need to check if this struct/union is "integer" like.  For
+	     this to be true, its size must be less than or equal to
+	     INT_REGISTER_SIZE and the offset of each addressable
+	     subfield must be zero.  Note that bit fields are not
+	     addressable, and unions always start at offset zero.  If any
+	     of the subfields is a floating point type, the struct/union
+	     cannot be an integer type.  */
+
+	  /* For each field in the object, check:
+	     1) Is it FP? --> yes, nRc = 1;
+	     2) Is it addressable (bitpos != 0) and
+	     not packed (bitsize == 0)?
+	     --> yes, nRc = 1
+	  */
+
+	  for (i = 0; i < TYPE_NFIELDS (type); i++)
 	    {
-	      /* Bitfields are not addressable.  If the field bitsize is 
-	         zero, then the field is not packed.  Hence it cannot be
-	         a bitfield or any other packed type.  */
-	      if (TYPE_FIELD_BITSIZE (type, i) == 0)
+	      enum type_code field_type_code;
+
+	      field_type_code
+		= TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (type,
+							     i)));
+
+	      /* Is it a floating point type field?  */
+	      if (field_type_code == TYPE_CODE_FLT)
 		{
 		  nRc = 1;
 		  break;
 		}
+
+	      /* If bitpos != 0, then we have to care about it.  */
+	      if (TYPE_FIELD_BITPOS (type, i) != 0)
+		{
+		  /* Bitfields are not addressable.  If the field bitsize is 
+		     zero, then the field is not packed.  Hence it cannot be
+		     a bitfield or any other packed type.  */
+		  if (TYPE_FIELD_BITSIZE (type, i) == 0)
+		    {
+		      nRc = 1;
+		      break;
+		    }
+		}
 	    }
 	}
-    }
 
-  return nRc;
+      return nRc;
+    }
 }
 
 /* Write into appropriate registers a function return value of type
@@ -9238,12 +9245,11 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
 	  || arm_return_in_memory (gdbarch, valtype))
 	return RETURN_VALUE_STRUCT_CONVENTION;
     }
-
-  /* AAPCS returns complex types longer than a register in memory.  */
-  if (tdep->arm_abi != ARM_ABI_APCS
-      && TYPE_CODE (valtype) == TYPE_CODE_COMPLEX
-      && TYPE_LENGTH (valtype) > INT_REGISTER_SIZE)
-    return RETURN_VALUE_STRUCT_CONVENTION;
+  else if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX)
+    {
+      if (arm_return_in_memory (gdbarch, valtype))
+	return RETURN_VALUE_STRUCT_CONVENTION;
+    }
 
   if (writebuf)
     arm_store_return_value (valtype, regcache, writebuf);
-- 
1.9.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 0/2] PR 19051: support of inferior call with gnu vector support on ARM
@ 2015-11-11 10:54 Yao Qi
  2015-11-11 10:54 ` [PATCH 1/2] Refactor arm_return_in_memory Yao Qi
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Yao Qi @ 2015-11-11 10:54 UTC (permalink / raw)
  To: gdb-patches

Hi,
This patch series fixes fails in gdb.base/gnu_vector.exp on ARM, as
reported in PR 19051.  Patch #1 is a refactoring patch, patch #2 is
the major one.

I test them on arm-linux with both hard-float and soft-float.  I don't
test them against bare-metal target.  In my test, I include this patch
fixing existing problems in gdb.base/gnu_vector.exp

  [PATCH] gdb.base/gnu_vector.exp: Don't test output from the inferior
  https://sourceware.org/ml/gdb-patches/2015-11/msg00226.html

*** BLURB HERE ***

Yao Qi (2):
  Refactor arm_return_in_memory
  PR 19051: support of inferior call with gnu vector support on ARM

 gdb/arm-tdep.c | 226 ++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 136 insertions(+), 90 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/2] PR 19051: support of inferior call with gnu vector support on ARM
  2015-11-11 10:54 [PATCH 0/2] PR 19051: support of inferior call with gnu vector support on ARM Yao Qi
  2015-11-11 10:54 ` [PATCH 1/2] Refactor arm_return_in_memory Yao Qi
@ 2015-11-11 10:54 ` Yao Qi
  2015-11-13 15:13 ` [PATCH 0/2] " Yao Qi
  2 siblings, 0 replies; 4+ messages in thread
From: Yao Qi @ 2015-11-11 10:54 UTC (permalink / raw)
  To: gdb-patches

This patch teaches GDB to support gnu vector in inferior calls.  As a
result, fails in gdb.base/gnu_vector.exp are fixed.  The calling
convention of gnu vector isn't documented in the AAPCS, because it
is the GCC extension.  I checked the gcc/config/arm/arm.c, understand
how GCC pass arguments and return values, and do the same in GDB side.

The patch is tested with both hard float and soft float on arm-linux.

gdb:

2015-11-11  Yao Qi  <yao.qi@linaro.org>

	PR tdep/19051
	* arm-tdep.c (arm_type_align): Return the right alignment
	value for vector.
	(arm_vfp_cprc_sub_candidate): Return true for 64-bit and
	128-bit vector types.
	(arm_return_in_memory): Handel vector type.
---
 gdb/arm-tdep.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 54 insertions(+), 14 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index f52f03a..83ce926 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3446,8 +3446,18 @@ arm_type_align (struct type *t)
       return TYPE_LENGTH (t);
 
     case TYPE_CODE_ARRAY:
+      if (TYPE_VECTOR (t))
+	{
+	  /* Use the natural alignment for vector types (the same for
+	     scalar type), but the maximum alignment is 64-bit.  */
+	  if (TYPE_LENGTH (t) > 8)
+	    return 8;
+	  else
+	    return TYPE_LENGTH (t);
+	}
+      else
+	return arm_type_align (TYPE_TARGET_TYPE (t));
     case TYPE_CODE_COMPLEX:
-      /* TODO: What about vector types?  */
       return arm_type_align (TYPE_TARGET_TYPE (t));
 
     case TYPE_CODE_STRUCT:
@@ -3594,21 +3604,44 @@ arm_vfp_cprc_sub_candidate (struct type *t,
 
     case TYPE_CODE_ARRAY:
       {
-	int count;
-	unsigned unitlen;
-	count = arm_vfp_cprc_sub_candidate (TYPE_TARGET_TYPE (t), base_type);
-	if (count == -1)
-	  return -1;
-	if (TYPE_LENGTH (t) == 0)
+	if (TYPE_VECTOR (t))
 	  {
-	    gdb_assert (count == 0);
-	    return 0;
+	    /* A 64-bit or 128-bit containerized vector type are VFP
+	       CPRCs.  */
+	    switch (TYPE_LENGTH (t))
+	      {
+	      case 8:
+		if (*base_type == VFP_CPRC_UNKNOWN)
+		  *base_type = VFP_CPRC_VEC64;
+		return 1;
+	      case 16:
+		if (*base_type == VFP_CPRC_UNKNOWN)
+		  *base_type = VFP_CPRC_VEC128;
+		return 1;
+	      default:
+		return -1;
+	      }
+	  }
+	else
+	  {
+	    int count;
+	    unsigned unitlen;
+
+	    count = arm_vfp_cprc_sub_candidate (TYPE_TARGET_TYPE (t),
+						base_type);
+	    if (count == -1)
+	      return -1;
+	    if (TYPE_LENGTH (t) == 0)
+	      {
+		gdb_assert (count == 0);
+		return 0;
+	      }
+	    else if (count == 0)
+	      return -1;
+	    unitlen = arm_vfp_cprc_unit_length (*base_type);
+	    gdb_assert ((TYPE_LENGTH (t) % unitlen) == 0);
+	    return TYPE_LENGTH (t) / unitlen;
 	  }
-	else if (count == 0)
-	  return -1;
-	unitlen = arm_vfp_cprc_unit_length (*base_type);
-	gdb_assert ((TYPE_LENGTH (t) % unitlen) == 0);
-	return TYPE_LENGTH (t) / unitlen;
       }
       break;
 
@@ -9002,6 +9035,13 @@ arm_return_in_memory (struct gdbarch *gdbarch, struct type *type)
       && TYPE_CODE_ARRAY != code && TYPE_CODE_COMPLEX != code)
     return 0;
 
+  if (TYPE_CODE_ARRAY == code && TYPE_VECTOR (type))
+    {
+      /* Vector values should be returned using ARM registers if they
+	 are not over 16 bytes.  */
+      return (TYPE_LENGTH (type) > 16);
+    }
+
   if (gdbarch_tdep (gdbarch)->arm_abi != ARM_ABI_APCS)
     {
       /* The AAPCS says all aggregates not larger than a word are returned
-- 
1.9.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] PR 19051: support of inferior call with gnu vector support on ARM
  2015-11-11 10:54 [PATCH 0/2] PR 19051: support of inferior call with gnu vector support on ARM Yao Qi
  2015-11-11 10:54 ` [PATCH 1/2] Refactor arm_return_in_memory Yao Qi
  2015-11-11 10:54 ` [PATCH 2/2] PR 19051: support of inferior call with gnu vector support on ARM Yao Qi
@ 2015-11-13 15:13 ` Yao Qi
  2 siblings, 0 replies; 4+ messages in thread
From: Yao Qi @ 2015-11-13 15:13 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

Yao Qi <qiyaoltc@gmail.com> writes:

> This patch series fixes fails in gdb.base/gnu_vector.exp on ARM, as
> reported in PR 19051.  Patch #1 is a refactoring patch, patch #2 is
> the major one.
>
> I test them on arm-linux with both hard-float and soft-float.  I don't
> test them against bare-metal target.  In my test, I include this patch
> fixing existing problems in gdb.base/gnu_vector.exp
>
>   [PATCH] gdb.base/gnu_vector.exp: Don't test output from the inferior
>   https://sourceware.org/ml/gdb-patches/2015-11/msg00226.html

I pushed them in.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-11-13 15:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-11 10:54 [PATCH 0/2] PR 19051: support of inferior call with gnu vector support on ARM Yao Qi
2015-11-11 10:54 ` [PATCH 1/2] Refactor arm_return_in_memory Yao Qi
2015-11-11 10:54 ` [PATCH 2/2] PR 19051: support of inferior call with gnu vector support on ARM Yao Qi
2015-11-13 15:13 ` [PATCH 0/2] " Yao Qi

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).