193 lines
7.6 KiB
Diff
193 lines
7.6 KiB
Diff
|
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 9a3b02f028d..b7106542b5d 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_ia64_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_ia64_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_ia64_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_ia64_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_ia64_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_ia64_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
|