aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2018-03-12 18:37:39 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2018-03-12 18:37:39 +0100
commitdf4cfec5540bfb982bfec374346493bed6608fa4 (patch)
tree08da92b79cac1ae80062cf5a906b0c8ee8daf456
parent37f71cead0f506b45a46d817d38c51d7e7690aac (diff)
downloadgcc-df4cfec5540bfb982bfec374346493bed6608fa4.zip
gcc-df4cfec5540bfb982bfec374346493bed6608fa4.tar.gz
gcc-df4cfec5540bfb982bfec374346493bed6608fa4.tar.bz2
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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/rs6000/rs6000.c12
2 files changed, 14 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cbdd4d2..f9f986b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
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/84780
* combine.c (can_combine_p): Check for a 2-insn combination whether
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 479f549..1db88d0 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -11449,13 +11449,13 @@ is_complex_IBM_long_double (machine_mode mode)
registers. */
static bool
-abi_v4_pass_in_fpr (machine_mode mode)
+abi_v4_pass_in_fpr (machine_mode mode, bool named)
{
if (!TARGET_HARD_FLOAT)
return false;
- if (TARGET_SINGLE_FLOAT && mode == SFmode)
+ if (mode == DFmode)
return true;
- if (TARGET_DOUBLE_FLOAT && mode == DFmode)
+ if (mode == SFmode && named)
return true;
/* ABI_V4 passes complex IBM long double in 8 gprs.
Stupid, but we can't change the ABI now. */
@@ -11926,7 +11926,7 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode,
}
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
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,
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
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,
align = 1;
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. */
reg = fpr;