Hi all,

This patch adds proper rtx costing logic for floating point fma operations on arm. It also handles the fma+neg combinations that can be expressed with vfms,vfnma or vfnms instructions.
Not much else to say here...

Tested and boostrapped on arm-none-linux-gnueabihf.

Ok for next stage1?

Thanks,
Kyrill

2014-03-24  Kyrylo Tkachov  <kyrylo.tkac...@arm.com>

    * config/arm/arm.c (arm_new_rtx_costs): Handle FMA.
commit 9cebc525c432e4a87ead5b513b70c99dff6628c8
Author: Kyrylo Tkachov <kyrylo.tkac...@arm.com>
Date:   Thu Mar 20 09:13:06 2014 +0000

    [ARM] Cost FMA operations properly.

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 5619ebd..e7a0530 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -10673,6 +10673,36 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
       *cost = LIBCALL_COST (1);
       return false;
 
+    case FMA:
+      if (TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA)
+        {
+          rtx op0 = XEXP (x, 0);
+          rtx op1 = XEXP (x, 1);
+          rtx op2 = XEXP (x, 2);
+
+          *cost = COSTS_N_INSNS (1);
+
+          /* vfms or vfnma.  */
+          if (GET_CODE (op0) == NEG)
+            op0 = XEXP (op0, 0);
+
+          /* vfnms or vfnma.  */
+          if (GET_CODE (op2) == NEG)
+            op2 = XEXP (op2, 0);
+
+          *cost += rtx_cost (op0, FMA, 0, speed_p);
+          *cost += rtx_cost (op1, FMA, 1, speed_p);
+          *cost += rtx_cost (op2, FMA, 2, speed_p);
+
+          if (speed_p)
+            *cost += extra_cost->fp[mode ==DFmode].fma;
+
+          return true;
+        }
+
+      *cost = LIBCALL_COST (1);
+      return false;
+
     case FIX:
     case UNSIGNED_FIX:
       if (TARGET_HARD_FLOAT)

Reply via email to