aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Pinski <apinski@cavium.com>2014-06-03 15:42:47 -0700
committerAndrew Pinski <pinskia@gcc.gnu.org>2014-06-03 15:42:47 -0700
commit2d5ffe4631cfaf0322d2174a32cbb65bbee6c18f (patch)
tree242fcb7d12bd154886f09c7ce75028e720c3e7d7
parent3ce7abdd2f20ef1111e7241627bb8021910cd3e8 (diff)
downloadgcc-2d5ffe4631cfaf0322d2174a32cbb65bbee6c18f.zip
gcc-2d5ffe4631cfaf0322d2174a32cbb65bbee6c18f.tar.gz
gcc-2d5ffe4631cfaf0322d2174a32cbb65bbee6c18f.tar.bz2
aarch64.c (aarch64_if_then_else_costs): New function.
2014-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. From-SVN: r211205
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/aarch64/aarch64.c126
2 files changed, 71 insertions, 60 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 544cf00..becfda8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 961e5c9..0cddba4 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -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: