diff mbox

[RS6000] complex long double ABI_V4 fix

Message ID 20160506062443.GC31342@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra May 6, 2016, 6:24 a.m. UTC
Revision 235792 regressed compat/scalar-by-value-6 for powerpc-linux
-m32 due to accidentally changing the ABI.  By another historical
accident, complex long double is stupidly passed in gprs for -m32.

Bootstrapped and regression tested powerpc64-linux.  Also fixes
gfortran.dg/{large_real_kind_2.F90,large_real_kind_form_io_1.f90}.
OK to apply?

	* config/rs6000/rs6000.c (rs6000_function_arg): Exclude IBM
	complex long double from args passed in fprs for ABI_V4.
	(rs6000_function_arg_boundary, rs6000_function_arg_advance_1,
	rs6000_gimplify_va_arg): Likewise.

Comments

Alan Modra May 6, 2016, 6:30 a.m. UTC | #1
On Fri, May 06, 2016 at 03:54:43PM +0930, Alan Modra wrote:
> Revision 235792 regressed compat/scalar-by-value-6 for powerpc-linux

Sorry, typo in the revision.  Should be 235794, git 3c62cae0.
Segher Boessenkool May 9, 2016, 2:43 p.m. UTC | #2
On Fri, May 06, 2016 at 03:54:43PM +0930, Alan Modra wrote:
> Revision 235792 regressed compat/scalar-by-value-6 for powerpc-linux
> -m32 due to accidentally changing the ABI.  By another historical
> accident, complex long double is stupidly passed in gprs for -m32.
> 
> Bootstrapped and regression tested powerpc64-linux.  Also fixes
> gfortran.dg/{large_real_kind_2.F90,large_real_kind_form_io_1.f90}.
> OK to apply?

> 	* config/rs6000/rs6000.c (rs6000_function_arg): Exclude IBM
> 	complex long double from args passed in fprs for ABI_V4.
> 	(rs6000_function_arg_boundary, rs6000_function_arg_advance_1,
> 	rs6000_gimplify_va_arg): Likewise.
> 
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index 1215925..9c7a37b 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -10142,6 +10142,7 @@ rs6000_function_arg_boundary (machine_mode mode, const_tree type)
>        && (GET_MODE_SIZE (mode) == 8
>  	  || (TARGET_HARD_FLOAT
>  	      && TARGET_FPRS
> +	      && !(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
>  	      && FLOAT128_2REG_P (mode))))

Since this monstruous, unreadable condition is used a lot, use a nicely named
helper function instead?


Segher
Michael Meissner May 9, 2016, 7:04 p.m. UTC | #3
On Fri, May 06, 2016 at 03:54:43PM +0930, Alan Modra wrote:
> Revision 235792 regressed compat/scalar-by-value-6 for powerpc-linux
> -m32 due to accidentally changing the ABI.  By another historical
> accident, complex long double is stupidly passed in gprs for -m32.

Sorry about the breakage.  Thanks for digging into it.
diff mbox

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 1215925..9c7a37b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -10142,6 +10142,7 @@  rs6000_function_arg_boundary (machine_mode mode, const_tree type)
       && (GET_MODE_SIZE (mode) == 8
 	  || (TARGET_HARD_FLOAT
 	      && TARGET_FPRS
+	      && !(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
 	      && FLOAT128_2REG_P (mode))))
     return 64;
   else if (FLOAT128_VECTOR_P (mode))
@@ -10524,7 +10525,8 @@  rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode,
       if (TARGET_HARD_FLOAT && TARGET_FPRS
 	  && ((TARGET_SINGLE_FLOAT && mode == SFmode)
 	      || (TARGET_DOUBLE_FLOAT && mode == DFmode)
-	      || FLOAT128_2REG_P (mode)
+	      || (!(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
+		  && FLOAT128_2REG_P (mode))
 	      || DECIMAL_FLOAT_MODE_P (mode)))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
@@ -11185,7 +11187,10 @@  rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
       if (TARGET_HARD_FLOAT && TARGET_FPRS
 	  && ((TARGET_SINGLE_FLOAT && mode == SFmode)
 	      || (TARGET_DOUBLE_FLOAT && mode == DFmode)
-	      || FLOAT128_2REG_P (mode)
+	      /* ABI_V4 passes complex IBM long double in 8 gprs.
+		 Stupid, but we can't change the ABI now.  */
+	      || (!(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
+		  && FLOAT128_2REG_P (mode))
 	      || DECIMAL_FLOAT_MODE_P (mode)))
 	{
 	  /* _Decimal128 must use an even/odd register pair.  This assumes
@@ -12107,19 +12112,21 @@  rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
   rsize = (size + 3) / 4;
   align = 1;
 
+  machine_mode mode = TYPE_MODE (type);
   if (TARGET_HARD_FLOAT && TARGET_FPRS
-      && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
+      && ((TARGET_SINGLE_FLOAT && mode == SFmode)
           || (TARGET_DOUBLE_FLOAT 
-              && (TYPE_MODE (type) == DFmode 
-		  || FLOAT128_2REG_P (TYPE_MODE (type))
-		  || DECIMAL_FLOAT_MODE_P (TYPE_MODE (type))))))
+              && (mode == DFmode
+		  || (!(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
+		      && FLOAT128_2REG_P (mode))
+		  || DECIMAL_FLOAT_MODE_P (mode)))))
     {
       /* FP args go in FP registers, if present.  */
       reg = fpr;
       n_reg = (size + 7) / 8;
       sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
       sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
-      if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
+      if (mode != SFmode && mode != SDmode)
 	align = 8;
     }
   else
@@ -12139,7 +12146,7 @@  rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
   addr = create_tmp_var (ptr_type_node, "addr");
 
   /*  AltiVec vectors never go in registers when -mabi=altivec.  */
-  if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
+  if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
     align = 16;
   else
     {
@@ -12160,7 +12167,7 @@  rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
 	}
       /* _Decimal128 is passed in even/odd fpr pairs; the stored
 	 reg number is 0 for f1, so we want to make it odd.  */
-      else if (reg == fpr && TYPE_MODE (type) == TDmode)
+      else if (reg == fpr && mode == TDmode)
 	{
 	  t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
 		      build_int_cst (TREE_TYPE (reg), 1));
@@ -12187,7 +12194,7 @@  rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
 	 FP register for 32-bit binaries.  */
       if (TARGET_32BIT
 	  && TARGET_HARD_FLOAT && TARGET_FPRS
-	  && TYPE_MODE (type) == SDmode)
+	  && mode == SDmode)
 	t = fold_build_pointer_plus_hwi (t, size);
 
       gimplify_assign (addr, t, pre_p);