public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] PowerPC: Add support for IEEE 128-bit format.
@ 2022-07-13 19:57 Carl Love
  2022-07-15 11:37 ` Ulrich Weigand
  0 siblings, 1 reply; 2+ messages in thread
From: Carl Love @ 2022-07-13 19:57 UTC (permalink / raw)
  To: gdb-patches, Ulrich Weigand, Will Schmidt, cel

GDB maintainers:

This patch adds the missing support to gdb for the IEEE 128-bit
floating point format.  GCC 12 now sets the default for 128-bit floats
to the IEEE 128-bit format rather instead of the IBM 128-bit long
double format.  This causes gdb to hit an assert in function
ppc64_sysv_abi_return_value in file gdb/ppc-sysv-tdep.c since the
PowerPC support is missing the IEEE 128-bit support.  

This patch adds the needed IEEE 128-bit support to file 
gdb/ppc-sysv-tdep.c.  The added support fixes numerous regression test
failures for PowerPC. 

The patch has been tested on Power 10 LE and Power 8 BE with no
regression errors.

Please let me know if this patch is acceptable for mainline.  Thanks.

                         Carl Love

---------------------------------------------------------
PowerPC: Add support for IEEE 128-bit format.

The test gdb.base/infcall-nested-structs-c.exp fails on a gdb assert
in function ppc64_sysv_abi_return_value in file gdb/ppc-sysv-tdep.c.  The
assert is due to the missing IEEE 128-bit support in file
gdb/ppc-sysv-tdep.c.

The IBM long double was the initial float 128-bit support added by IBM
The IEEE 128-bit support, which is similar IBM long double support, was
made the default starting with GCC 12.  The floating point format
differences include the number of bits used to encode the exponent
and significand.  Also, IBM long double values are passed in a pair of
floating point registers.  The  IEEE 128-bit value is passed in a single
vector register.

This patch fixes the gdb_assert (ok); in function
ppc64_sysv_abi_return_value in gdb/ppc-sysv-tdep.c by adding IEEE FLOAT
128-bit type support for PowerPC.

The patch has been tested on Power 10, ELFv2.  It fixes the following list
of regression failures on Power 10:

gdb.base/infcall-nested-structs-c.exp      192
gdb.base/infcall-nested-structs-c++.exp     76
gdb.base/structs.exp                         9

The patch has been tested on Power 8 BE which is ELFv1.
---
 gdb/ppc-sysv-tdep.c | 87 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 69 insertions(+), 18 deletions(-)

diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 6c2fd1bfc99..91cc28292c9 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -450,12 +450,17 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 		}
 	    }
 	  else if (len == 16
-		   && type->code () == TYPE_CODE_ARRAY
-		   && type->is_vector ()
-		   && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
+		   && ((type->code () == TYPE_CODE_ARRAY
+			&& type->is_vector ()
+			&& tdep->vector_abi == POWERPC_VEC_ALTIVEC)
+		   || (type->code () == TYPE_CODE_FLT
+		       && (gdbarch_long_double_format (gdbarch)
+			   == floatformats_ieee_quad))))
 	    {
 	      /* Vector parameter passed in an Altivec register, or
-		 when that runs out, 16 byte aligned stack location.  */
+		 when that runs out, 16 byte aligned stack location.
+		 IEEE FLOAT 128-bit also passes parameters in vector
+		 registers.  */
 	      if (vreg <= 13)
 		{
 		  if (write_pass)
@@ -1180,7 +1185,8 @@ ppc64_aggregate_candidate (struct type *type,
 
 static int
 ppc64_elfv2_abi_homogeneous_aggregate (struct type *type,
-				       struct type **elt_type, int *n_elts)
+				       struct type **elt_type, int *n_elts,
+				       struct gdbarch *gdbarch)
 {
   /* Complex types at the top level are treated separately.  However,
      complex types can be elements of homogeneous aggregates.  */
@@ -1193,9 +1199,20 @@ ppc64_elfv2_abi_homogeneous_aggregate (struct type *type,
 
       if (field_count > 0)
 	{
-	  int n_regs = ((field_type->code () == TYPE_CODE_FLT
-			 || field_type->code () == TYPE_CODE_DECFLOAT)?
-			(TYPE_LENGTH (field_type) + 7) >> 3 : 1);
+	  int n_regs;
+
+	  if (field_type->code () == TYPE_CODE_FLT
+	      && (gdbarch_long_double_format (gdbarch)
+		  == floatformats_ieee_quad))
+	    /* IEEE Float 128-bit uses one vector register.  */
+	    n_regs = 1;
+
+	  else if (field_type->code () == TYPE_CODE_FLT
+		   || field_type->code () == TYPE_CODE_DECFLOAT)
+	    n_regs = (TYPE_LENGTH (field_type) + 7) >> 3;
+
+	  else
+	    n_regs = 1;
 
 	  /* The ELFv2 ABI allows homogeneous aggregates to occupy
 	     up to 8 registers.  */
@@ -1422,7 +1439,16 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
   ppc_gdbarch_tdep *tdep = (ppc_gdbarch_tdep *) gdbarch_tdep (gdbarch);
 
   if (type->code () == TYPE_CODE_FLT
-      || type->code () == TYPE_CODE_DECFLOAT)
+      && TYPE_LENGTH (type) == 16
+      && (gdbarch_long_double_format (gdbarch)
+	  == floatformats_ieee_quad))
+    {
+      /* IEEE FLOAT128, args in vector registers.  */
+      ppc64_sysv_abi_push_val (gdbarch, val, TYPE_LENGTH (type), 0, argpos);
+      ppc64_sysv_abi_push_vreg (gdbarch, val, argpos);
+    }
+  else if (type->code () == TYPE_CODE_FLT
+	   || type->code () == TYPE_CODE_DECFLOAT)
     {
       /* Floating-point scalars are passed in floating-point registers.  */
       ppc64_sysv_abi_push_val (gdbarch, val, TYPE_LENGTH (type), 0, argpos);
@@ -1494,14 +1520,22 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
 	 single floating-point value, at any level of nesting of
 	 single-member structs, are passed in floating-point registers.  */
       if (type->code () == TYPE_CODE_STRUCT
-	  && type->num_fields () == 1)
+	  && type->num_fields () == 1 && tdep->elf_abi == POWERPC_ELF_V1)
 	{
 	  while (type->code () == TYPE_CODE_STRUCT
 		 && type->num_fields () == 1)
 	    type = check_typedef (type->field (0).type ());
 
-	  if (type->code () == TYPE_CODE_FLT)
-	    ppc64_sysv_abi_push_freg (gdbarch, type, val, argpos);
+	  if (type->code () == TYPE_CODE_FLT) {
+	    /* Handle the case of 128-bit floats for both IEEE and IBM long double
+	       formats.  */
+	    if (TYPE_LENGTH (type) == 16
+		&& (gdbarch_long_double_format (gdbarch)
+		    == floatformats_ieee_quad))
+	      ppc64_sysv_abi_push_vreg (gdbarch, val, argpos);
+	    else
+	      ppc64_sysv_abi_push_freg (gdbarch, type, val, argpos);
+	  }
 	}
 
       /* In the ELFv2 ABI, homogeneous floating-point or vector
@@ -1511,13 +1545,23 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
 	  struct type *eltype;
 	  int i, nelt;
 
-	  if (ppc64_elfv2_abi_homogeneous_aggregate (type, &eltype, &nelt))
+	  if (ppc64_elfv2_abi_homogeneous_aggregate (type, &eltype, &nelt,
+						     gdbarch))
 	    for (i = 0; i < nelt; i++)
 	      {
 		const gdb_byte *elval = val + i * TYPE_LENGTH (eltype);
 
 		if (eltype->code () == TYPE_CODE_FLT
-		    || eltype->code () == TYPE_CODE_DECFLOAT)
+		    && TYPE_LENGTH (eltype) == 16
+		    && (gdbarch_long_double_format (gdbarch)
+			== floatformats_ieee_quad))
+                 /* IEEE FLOAT128, args in vector registers.  */
+                 ppc64_sysv_abi_push_vreg (gdbarch, elval, argpos);
+
+		else if (eltype->code () == TYPE_CODE_FLT
+                          || eltype->code () == TYPE_CODE_DECFLOAT)
+		    /* IBM long double and all other floats and decfloats, args
+		       are in a pair of floating point registers.  */
 		  ppc64_sysv_abi_push_freg (gdbarch, eltype, elval, argpos);
 		else if (eltype->code () == TYPE_CODE_ARRAY
 			 && eltype->is_vector ()
@@ -1871,10 +1915,16 @@ ppc64_sysv_abi_return_value_base (struct gdbarch *gdbarch, struct type *valtype,
       return 1;
     }
 
-  /* AltiVec vectors are returned in VRs starting at v2.  */
+  /* AltiVec vectors are returned in VRs starting at v2.
+     IEEE FLOAT 128-bit are stored in vector register.  */
+
   if (TYPE_LENGTH (valtype) == 16
-      && valtype->code () == TYPE_CODE_ARRAY && valtype->is_vector ()
-      && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
+      && ((valtype->code () == TYPE_CODE_ARRAY
+	   && valtype->is_vector ()
+	   && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
+	  || (valtype->code () == TYPE_CODE_FLT
+	      && (gdbarch_long_double_format (gdbarch)
+		  == floatformats_ieee_quad))))
     {
       int regnum = tdep->ppc_vr0_regnum + 2 + index;
 
@@ -2012,7 +2062,8 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function,
   /* In the ELFv2 ABI, homogeneous floating-point or vector
      aggregates are returned in registers.  */
   if (tdep->elf_abi == POWERPC_ELF_V2
-      && ppc64_elfv2_abi_homogeneous_aggregate (valtype, &eltype, &nelt)
+      && ppc64_elfv2_abi_homogeneous_aggregate (valtype, &eltype, &nelt,
+						gdbarch)
       && (eltype->code () == TYPE_CODE_FLT
 	  || eltype->code () == TYPE_CODE_DECFLOAT
 	  || (eltype->code () == TYPE_CODE_ARRAY
-- 
2.36.1



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

* Re: [PATCH] PowerPC: Add support for IEEE 128-bit format.
  2022-07-13 19:57 [PATCH] PowerPC: Add support for IEEE 128-bit format Carl Love
@ 2022-07-15 11:37 ` Ulrich Weigand
  0 siblings, 0 replies; 2+ messages in thread
From: Ulrich Weigand @ 2022-07-15 11:37 UTC (permalink / raw)
  To: gdb-patches, will_schmidt, cel

Carl Love <cel@us.ibm.com> wrote:

>PowerPC: Add support for IEEE 128-bit format.

This is OK.

Thanks,
Ulrich


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

end of thread, other threads:[~2022-07-15 11:37 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-13 19:57 [PATCH] PowerPC: Add support for IEEE 128-bit format Carl Love
2022-07-15 11:37 ` Ulrich Weigand

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