Commit df4cfec5 by Segher Boessenkool Committed by Segher Boessenkool

rs6000: sysv: Don't pass SFmode in varargs in FPRs

This makes the float32-basic.c testcase work on sysv (32-bit Linux).

"float" is promoted to "double" for varargs.  The ABI also only defines
the use of double precision in varargs.  But _Float32 is not promoted.
Since there is no way of passing single-precision float in FPRs we
should pass SFmode in GPRs (or memory) instead.  This is similar to
the 64-bit ABI.

From-SVN: r258454
parent 37f71cea
2018-03-12 Segher Boessenkool <segher@kernel.crashing.org> 2018-03-12 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/rs6000.c (abi_v4_pass_in_fpr): Add bool "named"
parameter. Use it for SFmode.
(rs6000_function_arg_advance_1): Adjust.
(rs6000_function_arg): Adjust.
(rs6000_gimplify_va_arg): Pass false for that new parameter.
2018-03-12 Segher Boessenkool <segher@kernel.crashing.org>
PR rtl-optimization/84169 PR rtl-optimization/84169
PR rtl-optimization/84780 PR rtl-optimization/84780
* combine.c (can_combine_p): Check for a 2-insn combination whether * combine.c (can_combine_p): Check for a 2-insn combination whether
......
...@@ -11449,13 +11449,13 @@ is_complex_IBM_long_double (machine_mode mode) ...@@ -11449,13 +11449,13 @@ is_complex_IBM_long_double (machine_mode mode)
registers. */ registers. */
static bool static bool
abi_v4_pass_in_fpr (machine_mode mode) abi_v4_pass_in_fpr (machine_mode mode, bool named)
{ {
if (!TARGET_HARD_FLOAT) if (!TARGET_HARD_FLOAT)
return false; return false;
if (TARGET_SINGLE_FLOAT && mode == SFmode) if (mode == DFmode)
return true; return true;
if (TARGET_DOUBLE_FLOAT && mode == DFmode) if (mode == SFmode && named)
return true; return true;
/* ABI_V4 passes complex IBM long double in 8 gprs. /* ABI_V4 passes complex IBM long double in 8 gprs.
Stupid, but we can't change the ABI now. */ Stupid, but we can't change the ABI now. */
...@@ -11926,7 +11926,7 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode, ...@@ -11926,7 +11926,7 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode,
} }
else if (DEFAULT_ABI == ABI_V4) else if (DEFAULT_ABI == ABI_V4)
{ {
if (abi_v4_pass_in_fpr (mode)) if (abi_v4_pass_in_fpr (mode, named))
{ {
/* _Decimal128 must use an even/odd register pair. This assumes /* _Decimal128 must use an even/odd register pair. This assumes
that the register number is odd when fregno is odd. */ that the register number is odd when fregno is odd. */
...@@ -12478,7 +12478,7 @@ rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode, ...@@ -12478,7 +12478,7 @@ rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
else if (abi == ABI_V4) else if (abi == ABI_V4)
{ {
if (abi_v4_pass_in_fpr (mode)) if (abi_v4_pass_in_fpr (mode, named))
{ {
/* _Decimal128 must use an even/odd register pair. This assumes /* _Decimal128 must use an even/odd register pair. This assumes
that the register number is odd when fregno is odd. */ that the register number is odd when fregno is odd. */
...@@ -13402,7 +13402,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, ...@@ -13402,7 +13402,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
align = 1; align = 1;
machine_mode mode = TYPE_MODE (type); machine_mode mode = TYPE_MODE (type);
if (abi_v4_pass_in_fpr (mode)) if (abi_v4_pass_in_fpr (mode, false))
{ {
/* FP args go in FP registers, if present. */ /* FP args go in FP registers, if present. */
reg = fpr; reg = fpr;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment