diff options
author | Yvan Roux <yvan.roux@linaro.org> | 2016-09-02 09:58:35 +0200 |
---|---|---|
committer | Yvan Roux <yvan.roux@linaro.org> | 2016-09-07 22:08:23 +0200 |
commit | 516134a1f6f90ac712ac9354ba8131dcac349eb5 (patch) | |
tree | ec8e4be06da0d6a53ef1136ac727ce41fd175d25 | |
parent | dc7ea65bae8a93c6bb20038e8bf47832be9a8114 (diff) |
gcc/
Backport from trunk r237440.
2015-06-14 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/aarch64/aarch64.c (aarch64_mask_and_shift_for_ubfiz_p):
New function.
(aarch64_rtx_costs): Use it. Rewrite CONST_INT_P (op1) case to handle
mask+shift version.
* config/aarch64/aarch64-protos.h (aarch64_mask_and_shift_for_ubfiz_p):
New prototype.
* config/aarch64/aarch64.md (*andim_ashift<mode>_bfiz): Replace
matching condition with aarch64_mask_and_shift_for_ubfiz_p.
Change-Id: Ic17811963cafa2a514ab4db02fdde3937de01e22
-rw-r--r-- | gcc/config/aarch64/aarch64-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 43 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 4 |
3 files changed, 37 insertions, 11 deletions
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 3e0a0a37ec0..e8c2ac8d258 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -318,6 +318,7 @@ bool aarch64_is_noplt_call_p (rtx); bool aarch64_label_mentioned_p (rtx); void aarch64_declare_function_name (FILE *, const char*, tree); bool aarch64_legitimate_pic_operand_p (rtx); +bool aarch64_mask_and_shift_for_ubfiz_p (machine_mode, rtx, rtx); bool aarch64_modes_tieable_p (machine_mode mode1, machine_mode mode2); bool aarch64_zero_extend_const_eq (machine_mode, rtx, machine_mode, rtx); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 0826a244ffa..6587ba26d50 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -6170,6 +6170,19 @@ aarch64_extend_bitfield_pattern_p (rtx x) return op; } +/* Return true if the mask and a shift amount from an RTX of the form + (x << SHFT_AMNT) & MASK are valid to combine into a UBFIZ instruction of + mode MODE. See the *andim_ashift<mode>_bfiz pattern. */ + +bool +aarch64_mask_and_shift_for_ubfiz_p (machine_mode mode, rtx mask, rtx shft_amnt) +{ + return CONST_INT_P (mask) && CONST_INT_P (shft_amnt) + && INTVAL (shft_amnt) < GET_MODE_BITSIZE (mode) + && exact_log2 ((INTVAL (mask) >> INTVAL (shft_amnt)) + 1) >= 0 + && (INTVAL (mask) & ((1 << INTVAL (shft_amnt)) - 1)) == 0; +} + /* 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 @@ -6744,17 +6757,31 @@ cost_plus: if (GET_MODE_CLASS (mode) == MODE_INT) { - /* We possibly get the immediate for free, this is not - modelled. */ - if (CONST_INT_P (op1) - && aarch64_bitmask_imm (INTVAL (op1), mode)) + if (CONST_INT_P (op1)) { - *cost += rtx_cost (op0, mode, (enum rtx_code) code, 0, speed); + /* We have a mask + shift version of a UBFIZ + i.e. the *andim_ashift<mode>_bfiz pattern. */ + if (GET_CODE (op0) == ASHIFT + && aarch64_mask_and_shift_for_ubfiz_p (mode, op1, + XEXP (op0, 1))) + { + *cost += rtx_cost (XEXP (op0, 0), mode, + (enum rtx_code) code, 0, speed); + if (speed) + *cost += extra_cost->alu.bfx; - if (speed) - *cost += extra_cost->alu.logical; + return true; + } + else if (aarch64_bitmask_imm (INTVAL (op1), mode)) + { + /* We possibly get the immediate for free, this is not + modelled. */ + *cost += rtx_cost (op0, mode, (enum rtx_code) code, 0, speed); + if (speed) + *cost += extra_cost->alu.logical; - return true; + return true; + } } else { diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 04994273464..02d71b99a5a 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -4375,9 +4375,7 @@ (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r") (match_operand 2 "const_int_operand" "n")) (match_operand 3 "const_int_operand" "n")))] - "(INTVAL (operands[2]) < (<GPI:sizen>)) - && exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0 - && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0" + "aarch64_mask_and_shift_for_ubfiz_p (<MODE>mode, operands[3], operands[2])" "ubfiz\\t%<w>0, %<w>1, %2, %P3" [(set_attr "type" "bfm")] ) |