rs6000: sysv: Don't pass SFmode in varargs in FPRs
authorSegher Boessenkool <segher@kernel.crashing.org>
Mon, 12 Mar 2018 17:37:39 +0000 (18:37 +0100)
committerSegher Boessenkool <segher@gcc.gnu.org>
Mon, 12 Mar 2018 17:37:39 +0000 (18:37 +0100)
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

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index cbdd4d2002a2ff4592a120757fbb90b0b395cf95..f9f986bfab58be341ee3e2f33bc8b615793b58dc 100644 (file)
@@ -1,3 +1,11 @@
+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
index 479f5492c2c34cdb6f4c456000f7fce87fbfd405..1db88d0a1d2d2be5fb348e68782626aa2f96b65b 100644 (file)
@@ -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;