2014-06-03 Andrew Pinski <apinski@cavium.com>
authorpinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Jun 2014 22:42:47 +0000 (22:42 +0000)
committerpinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Jun 2014 22:42:47 +0000 (22:42 +0000)
* config/aarch64/aarch64.c (aarch64_if_then_else_costs): New function.
(aarch64_rtx_costs): Use aarch64_if_then_else_costs.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@211205 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/aarch64/aarch64.c

index 544cf00..becfda8 100644 (file)
@@ -1,3 +1,8 @@
+014-06-03  Andrew Pinski  <apinski@cavium.com>
+
+       * config/aarch64/aarch64.c (aarch64_if_then_else_costs): New function.
+       (aarch64_rtx_costs): Use aarch64_if_then_else_costs.
+
 2014-06-03  Kai Tietz  <ktietz@redhat.com>
 
        * config/i386/i386.c (ix86_function_value_regno_p): Disallow DX_REG
index 961e5c9..0cddba4 100644 (file)
@@ -4849,6 +4849,70 @@ aarch64_rtx_arith_op_extract_p (rtx x, enum machine_mode mode)
   return false;
 }
 
+/* Calculate the cost of calculating (if_then_else (OP0) (OP1) (OP2)),
+   storing it in *COST.  Result is true if the total cost of the operation
+   has now been calculated.  */
+static bool
+aarch64_if_then_else_costs (rtx op0, rtx op1, rtx op2, int *cost, bool speed)
+{
+  if (GET_CODE (op1) == PC || GET_CODE (op2) == PC)
+    {
+      /* Conditional branch.  */
+      if (GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
+       return true;
+      else
+       {
+         if (GET_CODE (op0) == NE
+             || GET_CODE (op0) == EQ)
+           {
+             rtx inner = XEXP (op0, 0);
+             rtx comparator = XEXP (op0, 1);
+
+             if (comparator == const0_rtx)
+               {
+                 /* TBZ/TBNZ/CBZ/CBNZ.  */
+                 if (GET_CODE (inner) == ZERO_EXTRACT)
+                   /* TBZ/TBNZ.  */
+                   *cost += rtx_cost (XEXP (inner, 0), ZERO_EXTRACT,
+                                      0, speed);
+               else
+                 /* CBZ/CBNZ.  */
+                 *cost += rtx_cost (inner, GET_CODE (op0), 0, speed);
+
+               return true;
+             }
+           }
+         else if (GET_CODE (op0) == LT
+                  || GET_CODE (op0) == GE)
+           {
+             rtx comparator = XEXP (op0, 1);
+
+             /* TBZ/TBNZ.  */
+             if (comparator == const0_rtx)
+               return true;
+           }
+       }
+    }
+  else if (GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
+    {
+      /* It's a conditional operation based on the status flags,
+        so it must be some flavor of CSEL.  */
+
+      /* CSNEG, CSINV, and CSINC are handled for free as part of CSEL.  */
+      if (GET_CODE (op1) == NEG
+          || GET_CODE (op1) == NOT
+          || (GET_CODE (op1) == PLUS && XEXP (op1, 1) == const1_rtx))
+       op1 = XEXP (op1, 0);
+
+      *cost += rtx_cost (op1, IF_THEN_ELSE, 1, speed);
+      *cost += rtx_cost (op2, IF_THEN_ELSE, 2, speed);
+      return true;
+    }
+
+  /* We don't know what this is, cost all operands.  */
+  return false;
+}
+
 /* Calculate the cost of calculating X, storing it in *COST.  Result
    is true if the total cost of the operation has now been calculated.  */
 static bool
@@ -5583,66 +5647,8 @@ cost_plus:
       return false;  /* All arguments need to be in registers.  */
 
     case IF_THEN_ELSE:
-      op2 = XEXP (x, 2);
-      op0 = XEXP (x, 0);
-      op1 = XEXP (x, 1);
-
-      if (GET_CODE (op1) == PC || GET_CODE (op2) == PC)
-        {
-          /* Conditional branch.  */
-          if (GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
-           return true;
-         else
-           {
-             if (GET_CODE (op0) == NE
-                 || GET_CODE (op0) == EQ)
-               {
-                 rtx inner = XEXP (op0, 0);
-                 rtx comparator = XEXP (op0, 1);
-
-                 if (comparator == const0_rtx)
-                   {
-                     /* TBZ/TBNZ/CBZ/CBNZ.  */
-                     if (GET_CODE (inner) == ZERO_EXTRACT)
-                       /* TBZ/TBNZ.  */
-                       *cost += rtx_cost (XEXP (inner, 0), ZERO_EXTRACT,
-                                          0, speed);
-                     else
-                       /* CBZ/CBNZ.  */
-                       *cost += rtx_cost (inner, GET_CODE (op0), 0, speed);
-
-                     return true;
-                   }
-               }
-             else if (GET_CODE (op0) == LT
-                      || GET_CODE (op0) == GE)
-               {
-                 rtx comparator = XEXP (op0, 1);
-
-                 /* TBZ/TBNZ.  */
-                 if (comparator == const0_rtx)
-                   return true;
-               }
-           }
-        }
-      else if (GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
-        {
-          /* It's a conditional operation based on the status flags,
-             so it must be some flavor of CSEL.  */
-
-          /* CSNEG, CSINV, and CSINC are handled for free as part of CSEL.  */
-          if (GET_CODE (op1) == NEG
-              || GET_CODE (op1) == NOT
-              || (GET_CODE (op1) == PLUS && XEXP (op1, 1) == const1_rtx))
-            op1 = XEXP (op1, 0);
-
-          *cost += rtx_cost (op1, IF_THEN_ELSE, 1, speed);
-          *cost += rtx_cost (op2, IF_THEN_ELSE, 2, speed);
-          return true;
-        }
-
-      /* We don't know what this is, cost all operands.  */
-      return false;
+      return aarch64_if_then_else_costs (XEXP (x, 0), XEXP (x, 1),
+                                        XEXP (x, 2), cost, speed);
 
     case EQ:
     case NE: