diff options
author | Than McIntosh <thanm@google.com> | 2015-10-16 12:24:12 -0400 |
---|---|---|
committer | Than McIntosh <thanm@google.com> | 2015-10-16 12:24:12 -0400 |
commit | 37248b072c78201ba30cf46e9c7d423aa9423956 (patch) | |
tree | d19836b2bd032f851dba73f542c25979aa850d4b /gcc-4.9 | |
parent | a8c075f72b231c37823661ba0d7d082a21cd39d9 (diff) | |
download | toolchain_gcc-37248b072c78201ba30cf46e9c7d423aa9423956.tar.gz toolchain_gcc-37248b072c78201ba30cf46e9c7d423aa9423956.tar.bz2 toolchain_gcc-37248b072c78201ba30cf46e9c7d423aa9423956.zip |
Fix for N9 kernel build.
Cherry-pick from trunk:
commit 39f4504dbc88d17c496cdf7b12fb0d32277d281d
Author: pinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue Jun 3 22:42:47 2014 +0000
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.
Bug: 24985248
Change-Id: Ic03ba2552615fca0aa0de6af47f47ae4cf074e3b
Diffstat (limited to 'gcc-4.9')
-rw-r--r-- | gcc-4.9/gcc/config/aarch64/aarch64.c | 136 |
1 files changed, 76 insertions, 60 deletions
diff --git a/gcc-4.9/gcc/config/aarch64/aarch64.c b/gcc-4.9/gcc/config/aarch64/aarch64.c index 09f2d2c5d..709799406 100644 --- a/gcc-4.9/gcc/config/aarch64/aarch64.c +++ b/gcc-4.9/gcc/config/aarch64/aarch64.c @@ -4825,6 +4825,80 @@ 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) +{ + rtx inner; + rtx comparator; + enum rtx_code cmpcode; + + if (COMPARISON_P (op0)) + { + inner = XEXP (op0, 0); + comparator = XEXP (op0, 1); + cmpcode = GET_CODE (op0); + } + else + { + inner = op0; + comparator = const0_rtx; + cmpcode = NE; + } + + if (GET_CODE (op1) == PC || GET_CODE (op2) == PC) + { + /* Conditional branch. */ + if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_CC) + return true; + else + { + if (cmpcode == NE || cmpcode == EQ) + { + 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, cmpcode, 0, speed); + + return true; + } + } + else if (cmpcode == LT || cmpcode == GE) + { + /* TBZ/TBNZ. */ + if (comparator == const0_rtx) + return true; + } + } + } + else if (GET_MODE_CLASS (GET_MODE (inner)) == 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 @@ -5572,66 +5646,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: |