Patchwork [5/N,s390] convert -mfused-add to -ffp-contract

login
register
mail settings
Submitter Richard Henderson
Date Nov. 12, 2010, 1:08 a.m.
Message ID <4CDC93A1.3090603@redhat.com>
Download mbox | patch
Permalink /patch/70904/
State New
Headers show

Comments

Richard Henderson - Nov. 12, 2010, 1:08 a.m.
On 11/11/2010 04:58 PM, Richard Henderson wrote:
> This backend was very easy to convert.  It did bring to mind the fact
> that the rtx costing needs adjusting for the other ports as well, or
> we'll lose out in combine when combinations of FMA and NEG don't get
> combined due to improper cost estimates.
> 
> Irritatingly, my hercules setup ran out of disk space while testing,
> so I didn't get a full run there.  But I know it builds at least.  ;-)
> 
> Ok?

Bah.

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index e976f8c..028380b 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -393,6 +393,7 @@  spu*-*-*)
 s390*-*-*)
 	cpu_type=s390
 	need_64bit_hwint=yes
+	extra_options="${extra_options} fused-madd.opt"
 	;;
 # Note the 'l'; we need to be able to match e.g. "shle" or "shl".
 sh[123456789lbe]*-*-* | sh-*-*)
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 11ca919..2c40b67 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -2464,21 +2464,6 @@  s390_rtx_costs (rtx x, int code, int outer_code, int *total,
 
     case PLUS:
     case MINUS:
-      /* Check for multiply and add.  */
-      if ((GET_MODE (x) == DFmode || GET_MODE (x) == SFmode)
-	  && GET_CODE (XEXP (x, 0)) == MULT
-	  && TARGET_HARD_FLOAT && TARGET_FUSED_MADD)
-	{
-	  /* This is the multiply and add case.  */
-	  if (GET_MODE (x) == DFmode)
-	    *total = s390_cost->madbr;
-	  else
-	    *total = s390_cost->maebr;
-	  *total += (rtx_cost (XEXP (XEXP (x, 0), 0), MULT, speed)
-		     + rtx_cost (XEXP (XEXP (x, 0), 1), MULT, speed)
-		     + rtx_cost (XEXP (x, 1), (enum rtx_code) code, speed));
-	  return true;  /* Do not do an additional recursive descent.  */
-	}
       *total = COSTS_N_INSNS (1);
       return false;
 
@@ -2541,6 +2526,28 @@  s390_rtx_costs (rtx x, int code, int outer_code, int *total,
 	}
       return false;
 
+    case FMA:
+      switch (GET_MODE (x))
+	{
+	case DFmode:
+	  *total = s390_cost->madbr;
+	  break;
+	case SFmode:
+	  *total = s390_cost->maebr;
+	  break;
+	default:
+	  return false;
+	}
+      /* Negate in the third argument is free: FMSUB.  */
+      if (GET_CODE (XEXP (x, 2)) == NEG)
+	{
+	  *total += (rtx_cost (XEXP (x, 0), FMA, speed)
+		     + rtx_cost (XEXP (x, 1), FMA, speed)
+		     + rtx_cost (XEXP (XEXP (x, 2), 0), FMA, speed));
+	  return true;
+	}
+      return false;
+
     case UDIV:
     case UMOD:
       if (GET_MODE (x) == TImode) 	       /* 128 bit division */
@@ -10511,7 +10518,7 @@  s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
 #define TARGET_ASM_CLOSE_PAREN ""
 
 #undef TARGET_DEFAULT_TARGET_FLAGS
-#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
+#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT)
 
 #undef TARGET_HANDLE_OPTION
 #define TARGET_HANDLE_OPTION s390_handle_option
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index ce8c3ce..701fca1 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -5488,12 +5488,12 @@ 
    (set_attr "type"     "fmul<mode>")])
 
 ; madbr, maebr, maxb, madb, maeb
-(define_insn "*fmadd<mode>"
+(define_insn "fma<mode>4"
   [(set (match_operand:DSF 0 "register_operand" "=f,f")
-	(plus:DSF (mult:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f")
-			    (match_operand:DSF 2 "nonimmediate_operand" "f,R"))
+	(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f")
+		 (match_operand:DSF 2 "nonimmediate_operand" "f,R")
 		 (match_operand:DSF 3 "register_operand" "0,0")))]
-  "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
+  "TARGET_HARD_FLOAT"
   "@
    ma<xde>br\t%0,%1,%2
    ma<xde>b\t%0,%1,%2"
@@ -5501,12 +5501,12 @@ 
    (set_attr "type"     "fmadd<mode>")])
 
 ; msxbr, msdbr, msebr, msxb, msdb, mseb
-(define_insn "*fmsub<mode>"
+(define_insn "fms<mode>4"
   [(set (match_operand:DSF 0 "register_operand" "=f,f")
-	(minus:DSF (mult:DSF (match_operand:DSF 1 "nonimmediate_operand" "f,f")
-			     (match_operand:DSF 2 "nonimmediate_operand" "f,R"))
-		 (match_operand:DSF 3 "register_operand" "0,0")))]
-  "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
+	(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f")
+		 (match_operand:DSF 2 "nonimmediate_operand" "f,R")
+		 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0"))))]
+  "TARGET_HARD_FLOAT"
   "@
    ms<xde>br\t%0,%1,%2
    ms<xde>b\t%0,%1,%2"
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index 9451b74..57ab838 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -42,10 +42,6 @@  mesa
 Target Report RejectNegative Negative(mzarch) InverseMask(ZARCH)
 ESA/390 architecture
 
-mfused-madd
-Target Report Mask(FUSED_MADD)
-Enable fused multiply/add instructions
-
 mhard-dfp
 Target Report Mask(HARD_DFP)
 Enable decimal floating point hardware support