[gdb/tdep] Fix PowerPC IEEE 128-bit format arg passing
On a powerpc system with gcc 12 built to default to 128-bit IEEE long double, I run into: ... (gdb) print find_max_long_double_real(4, ldc1, ldc2, ldc3, ldc4)^M $8 = 0 + 0i^M (gdb) FAIL: gdb.base/varargs.exp: print \ find_max_long_double_real(4, ldc1, ldc2, ldc3, ldc4) ... This is due to incorrect handling of the argument in ppc64_sysv_abi_push_param. Fix this and similar cases, and expand the test-case to test handling of homogeneous aggregates. Tested on ppc64le-linux, power 10. Co-Authored-By: Ulrich Weigand <uweigand@de.ibm.com> Tested-by: Carl Love <cel@us.ibm.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29543
This commit is contained in:
parent
77e6e213e0
commit
ff84aaf3e3
3 changed files with 49 additions and 6 deletions
|
@ -1444,7 +1444,7 @@ ppc64_sysv_abi_push_param (struct gdbarch *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_val (gdbarch, val, TYPE_LENGTH (type), 16, argpos);
|
||||
ppc64_sysv_abi_push_vreg (gdbarch, val, argpos);
|
||||
}
|
||||
else if (type->code () == TYPE_CODE_FLT
|
||||
|
@ -1514,7 +1514,10 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
|
|||
}
|
||||
else
|
||||
{
|
||||
ppc64_sysv_abi_push_val (gdbarch, val, TYPE_LENGTH (type), 0, argpos);
|
||||
/* Align == 0 is correct for ppc64_sysv_abi_push_freg,
|
||||
Align == 16 is correct for ppc64_sysv_abi_push_vreg.
|
||||
Default to 0. */
|
||||
int align = 0;
|
||||
|
||||
/* The ABI (version 1.9) specifies that structs containing a
|
||||
single floating-point value, at any level of nesting of
|
||||
|
@ -1532,7 +1535,10 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
|
|||
if (TYPE_LENGTH (type) == 16
|
||||
&& (gdbarch_long_double_format (gdbarch)
|
||||
== floatformats_ieee_quad))
|
||||
ppc64_sysv_abi_push_vreg (gdbarch, val, argpos);
|
||||
{
|
||||
ppc64_sysv_abi_push_vreg (gdbarch, val, argpos);
|
||||
align = 16;
|
||||
}
|
||||
else
|
||||
ppc64_sysv_abi_push_freg (gdbarch, type, val, argpos);
|
||||
}
|
||||
|
@ -1556,8 +1562,10 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
|
|||
&& (gdbarch_long_double_format (gdbarch)
|
||||
== floatformats_ieee_quad))
|
||||
/* IEEE FLOAT128, args in vector registers. */
|
||||
ppc64_sysv_abi_push_vreg (gdbarch, elval, argpos);
|
||||
|
||||
{
|
||||
ppc64_sysv_abi_push_vreg (gdbarch, elval, argpos);
|
||||
align = 16;
|
||||
}
|
||||
else if (eltype->code () == TYPE_CODE_FLT
|
||||
|| eltype->code () == TYPE_CODE_DECFLOAT)
|
||||
/* IBM long double and all other floats and decfloats, args
|
||||
|
@ -1567,9 +1575,14 @@ ppc64_sysv_abi_push_param (struct gdbarch *gdbarch,
|
|||
&& eltype->is_vector ()
|
||||
&& tdep->vector_abi == POWERPC_VEC_ALTIVEC
|
||||
&& TYPE_LENGTH (eltype) == 16)
|
||||
ppc64_sysv_abi_push_vreg (gdbarch, elval, argpos);
|
||||
{
|
||||
ppc64_sysv_abi_push_vreg (gdbarch, elval, argpos);
|
||||
align = 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ppc64_sysv_abi_push_val (gdbarch, val, TYPE_LENGTH (type), align, argpos);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,16 @@ long double _Complex ldc2 = 2.0L + 2.0Li;
|
|||
long double _Complex ldc3 = 3.0L + 3.0Li;
|
||||
long double _Complex ldc4 = 4.0L + 4.0Li;
|
||||
|
||||
struct sldc
|
||||
{
|
||||
long double _Complex ldc;
|
||||
};
|
||||
|
||||
struct sldc sldc1 = { 1.0L + 1.0Li };
|
||||
struct sldc sldc2 = { 2.0L + 2.0Li };
|
||||
struct sldc sldc3 = { 3.0L + 3.0Li };
|
||||
struct sldc sldc4 = { 4.0L + 4.0Li };
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
|
@ -201,4 +211,22 @@ find_max_long_double_real (int num_vals, ...)
|
|||
}
|
||||
|
||||
|
||||
long double _Complex
|
||||
find_max_struct_long_double_real (int num_vals, ...)
|
||||
{
|
||||
long double _Complex max = 0.0L + 0.0iL;
|
||||
struct sldc x;
|
||||
va_list argp;
|
||||
int i;
|
||||
|
||||
va_start(argp, num_vals);
|
||||
for (i = 0; i < num_vals; i++)
|
||||
{
|
||||
x = va_arg (argp, struct sldc);
|
||||
if (creall (max) < creal (x.ldc)) max = x.ldc;
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
#endif /* TEST_COMPLEX */
|
||||
|
|
|
@ -103,4 +103,6 @@ if [support_complex_tests] {
|
|||
set test "print find_max_long_double_real(4, ldc1, ldc2, ldc3, ldc4)"
|
||||
gdb_test $test ".*= 4 \\+ 4i"
|
||||
|
||||
set test "print find_max_struct_long_double_real(4, sldc1, sldc2, sldc3, sldc4)"
|
||||
gdb_test $test ".*= 4 \\+ 4i"
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue