diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-12-20 12:51:22 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-12-20 12:51:22 +0000 |
commit | abd3c800109b95f09af3b3f1a7a43d9b7631f21c (patch) | |
tree | 87a4afd30dc1d59b47bcd99fe6310f168476084b /gcc/optabs.c | |
parent | 27d229f709a928adc7c4e464509cc1633d127f3f (diff) | |
download | gcc-abd3c800109b95f09af3b3f1a7a43d9b7631f21c.zip gcc-abd3c800109b95f09af3b3f1a7a43d9b7631f21c.tar.gz gcc-abd3c800109b95f09af3b3f1a7a43d9b7631f21c.tar.bz2 |
Add a gen_int_shift_amount helper function
This patch adds a helper routine that constructs rtxes
for constant shift amounts, given the mode of the value
being shifted. As well as helping with the SVE patches, this
is one step towards allowing CONST_INTs to have a real mode.
One long-standing problem has been to decide what the mode
of a shift count should be for arbitrary rtxes (as opposed to those
directly tied to a target pattern). Realistic choices would be
the mode of the shifted elements, word_mode, QImode, a 64-bit mode,
or the same mode as the shift optabs (in which case what should the
mode be when the target doesn't have a pattern?)
For now the patch picks a 64-bit mode, but with a ??? comment.
2017-12-20 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* emit-rtl.h (gen_int_shift_amount): Declare.
* emit-rtl.c (gen_int_shift_amount): New function.
* asan.c (asan_emit_stack_protection): Use gen_int_shift_amount
instead of GEN_INT.
* calls.c (shift_return_value): Likewise.
* cse.c (fold_rtx): Likewise.
* dse.c (find_shift_sequence): Likewise.
* expmed.c (init_expmed_one_mode, store_bit_field_1, expand_shift_1)
(expand_shift, expand_smod_pow2): Likewise.
* lower-subreg.c (shift_cost): Likewise.
* optabs.c (expand_superword_shift, expand_doubleword_mult)
(expand_unop, expand_binop, shift_amt_for_vec_perm_mask)
(expand_vec_perm_var): Likewise.
* simplify-rtx.c (simplify_unary_operation_1): Likewise.
(simplify_binary_operation_1): Likewise.
* combine.c (try_combine, find_split_point, force_int_to_mode)
(simplify_shift_const_1, simplify_shift_const): Likewise.
(change_zero_ext): Likewise. Use simplify_gen_binary.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r255861
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index 3354e40..b0d82af 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -431,8 +431,9 @@ expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1, if (binoptab != ashr_optab) emit_move_insn (outof_target, CONST0_RTX (word_mode)); else - if (!force_expand_binop (word_mode, binoptab, - outof_input, GEN_INT (BITS_PER_WORD - 1), + if (!force_expand_binop (word_mode, binoptab, outof_input, + gen_int_shift_amount (word_mode, + BITS_PER_WORD - 1), outof_target, unsignedp, methods)) return false; } @@ -789,7 +790,8 @@ expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target, { int low = (WORDS_BIG_ENDIAN ? 1 : 0); int high = (WORDS_BIG_ENDIAN ? 0 : 1); - rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1); + rtx wordm1 = (umulp ? NULL_RTX + : gen_int_shift_amount (word_mode, BITS_PER_WORD - 1)); rtx product, adjust, product_high, temp; rtx op0_high = operand_subword_force (op0, high, mode); @@ -1190,7 +1192,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, unsigned int bits = GET_MODE_PRECISION (int_mode); if (CONST_INT_P (op1)) - newop1 = GEN_INT (bits - INTVAL (op1)); + newop1 = gen_int_shift_amount (int_mode, bits - INTVAL (op1)); else if (targetm.shift_truncation_mask (int_mode) == bits - 1) newop1 = negate_rtx (GET_MODE (op1), op1); else @@ -1412,7 +1414,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, /* Apply the truncation to constant shifts. */ if (double_shift_mask > 0 && CONST_INT_P (op1)) - op1 = GEN_INT (INTVAL (op1) & double_shift_mask); + op1 = gen_int_mode (INTVAL (op1) & double_shift_mask, op1_mode); if (op1 == CONST0_RTX (op1_mode)) return op0; @@ -1522,7 +1524,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, else { rtx into_temp1, into_temp2, outof_temp1, outof_temp2; - rtx first_shift_count, second_shift_count; + HOST_WIDE_INT first_shift_count, second_shift_count; optab reverse_unsigned_shift, unsigned_shift; reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD) @@ -1533,20 +1535,24 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, if (shift_count > BITS_PER_WORD) { - first_shift_count = GEN_INT (shift_count - BITS_PER_WORD); - second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count); + first_shift_count = shift_count - BITS_PER_WORD; + second_shift_count = 2 * BITS_PER_WORD - shift_count; } else { - first_shift_count = GEN_INT (BITS_PER_WORD - shift_count); - second_shift_count = GEN_INT (shift_count); + first_shift_count = BITS_PER_WORD - shift_count; + second_shift_count = shift_count; } + rtx first_shift_count_rtx + = gen_int_shift_amount (word_mode, first_shift_count); + rtx second_shift_count_rtx + = gen_int_shift_amount (word_mode, second_shift_count); into_temp1 = expand_binop (word_mode, unsigned_shift, - outof_input, first_shift_count, + outof_input, first_shift_count_rtx, NULL_RTX, unsignedp, next_methods); into_temp2 = expand_binop (word_mode, reverse_unsigned_shift, - into_input, second_shift_count, + into_input, second_shift_count_rtx, NULL_RTX, unsignedp, next_methods); if (into_temp1 != 0 && into_temp2 != 0) @@ -1559,10 +1565,10 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, emit_move_insn (into_target, inter); outof_temp1 = expand_binop (word_mode, unsigned_shift, - into_input, first_shift_count, + into_input, first_shift_count_rtx, NULL_RTX, unsignedp, next_methods); outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift, - outof_input, second_shift_count, + outof_input, second_shift_count_rtx, NULL_RTX, unsignedp, next_methods); if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0) @@ -2802,25 +2808,29 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target, if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing) { - temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target, - unsignedp, OPTAB_DIRECT); + temp = expand_binop (mode, rotl_optab, op0, + gen_int_shift_amount (mode, 8), + target, unsignedp, OPTAB_DIRECT); if (temp) return temp; } if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing) { - temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target, - unsignedp, OPTAB_DIRECT); + temp = expand_binop (mode, rotr_optab, op0, + gen_int_shift_amount (mode, 8), + target, unsignedp, OPTAB_DIRECT); if (temp) return temp; } last = get_last_insn (); - temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX, + temp1 = expand_binop (mode, ashl_optab, op0, + gen_int_shift_amount (mode, 8), NULL_RTX, unsignedp, OPTAB_WIDEN); - temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX, + temp2 = expand_binop (mode, lshr_optab, op0, + gen_int_shift_amount (mode, 8), NULL_RTX, unsignedp, OPTAB_WIDEN); if (temp1 && temp2) { @@ -5402,7 +5412,7 @@ shift_amt_for_vec_perm_mask (rtx sel) return NULL_RTX; } - return GEN_INT (first * bitsize); + return gen_int_shift_amount (GET_MODE (sel), first * bitsize); } /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */ @@ -5572,7 +5582,8 @@ expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target) NULL, 0, OPTAB_DIRECT); else sel = expand_simple_binop (selmode, ASHIFT, sel, - GEN_INT (exact_log2 (u)), + gen_int_shift_amount (selmode, + exact_log2 (u)), NULL, 0, OPTAB_DIRECT); gcc_assert (sel != NULL); |