This patch makes the AArch64 port use scalar_int_mode in various places. Other ports won't need this kind of change; we only need it for AArch64 because of the polynomial integers that are added by later patches.
The only change in functionality is in the rtx_costs handling of CONST_INT. If the caller doesn't supply a mode, we now pass word_mode rather than VOIDmode to aarch64_internal_mov_immediate. aarch64_movw_imm will therefore not now truncate large constants in this situation. gcc/ 2016-11-24 Richard Sandiford <richard.sandif...@arm.com> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> * config/aarch64/aarch64-protos.h (aarch64_and_bitmask_imm): Take a scalar_int_mode instead of a machine_mode. (aarch64_is_extend_from_extract): Likewise. (aarch64_mask_and_shift_for_ubfiz_p): Likewise. (aarch64_move_imm): Likewise. (aarch64_output_scalar_simd_mov_immediate): Likewise. (aarch64_simd_scalar_immediate_valid_for_move): Likewise. (aarch64_simd_attr_length_rglist): Delete. * config/aarch64/aarch64.c (aarch64_is_extend_from_extract): Take a scalar_int_mode instead of a machine_mode. (aarch64_add_offset): Likewise. (aarch64_internal_mov_immediate): Likewise (aarch64_add_constant_internal): Likewise. (aarch64_add_constant): Likewise. (aarch64_movw_imm): Likewise. (aarch64_and_bitmask_imm): Likewise. (aarch64_move_imm): Likewise. (aarch64_rtx_arith_op_extract_p): Likewise. (aarch64_mask_and_shift_for_ubfiz_p): Likewise. (aarch64_simd_scalar_immediate_valid_for_move): Likewise. Remove assert that the mode isn't a vector. (aarch64_output_scalar_simd_mov_immediate): Likewise. (aarch64_expand_mov_immediate): Update calls after above changes. (aarch64_output_casesi): Use as_a <scalar_int_mode>. (aarch64_strip_extend): Check for scalar integer modes. (aarch64_rtx_costs): Likewise, using wode_mode as the mode of a CONST_INT when the mode parameter is VOIDmode. * config/aarch64/predicates.md (aarch64_logical_and_immediate): Update call to aarch64_and_bitmask_imm. diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 803d4fc..17f1b93 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -298,7 +298,8 @@ int aarch64_get_condition_code (rtx); bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode); unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in); unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in); -bool aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, machine_mode mode); +bool aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, + scalar_int_mode mode); int aarch64_branch_cost (bool, bool); enum aarch64_symbol_type aarch64_classify_symbolic_expression (rtx); bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT); @@ -311,22 +312,21 @@ bool aarch64_function_arg_regno_p (unsigned); bool aarch64_fusion_enabled_p (enum aarch64_fusion_pairs); bool aarch64_gen_movmemqi (rtx *); bool aarch64_gimple_fold_builtin (gimple_stmt_iterator *); -bool aarch64_is_extend_from_extract (machine_mode, rtx, rtx); +bool aarch64_is_extend_from_extract (scalar_int_mode, rtx, rtx); bool aarch64_is_long_call_p (rtx); 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_mask_and_shift_for_ubfiz_p (scalar_int_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); -bool aarch64_move_imm (HOST_WIDE_INT, machine_mode); +bool aarch64_move_imm (HOST_WIDE_INT, scalar_int_mode); bool aarch64_mov_operand_p (rtx, machine_mode); -int aarch64_simd_attr_length_rglist (machine_mode); rtx aarch64_reverse_mask (machine_mode); bool aarch64_offset_7bit_signed_scaled_p (machine_mode, HOST_WIDE_INT); -char *aarch64_output_scalar_simd_mov_immediate (rtx, machine_mode); +char *aarch64_output_scalar_simd_mov_immediate (rtx, scalar_int_mode); char *aarch64_output_simd_mov_immediate (rtx, machine_mode, unsigned); bool aarch64_pad_arg_upward (machine_mode, const_tree); bool aarch64_pad_reg_upward (machine_mode, const_tree, bool); @@ -335,7 +335,7 @@ bool aarch64_regno_ok_for_index_p (int, bool); bool aarch64_simd_check_vect_par_cnst_half (rtx, machine_mode, bool); bool aarch64_simd_imm_scalar_p (rtx x, machine_mode mode); bool aarch64_simd_imm_zero_p (rtx, machine_mode); -bool aarch64_simd_scalar_immediate_valid_for_move (rtx, machine_mode); +bool aarch64_simd_scalar_immediate_valid_for_move (rtx, scalar_int_mode); bool aarch64_simd_shift_imm_p (rtx, machine_mode, bool); bool aarch64_simd_valid_immediate (rtx, machine_mode, bool, struct simd_immediate_info *); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index ed2e44b..d8019bf 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1118,7 +1118,7 @@ aarch64_is_noplt_call_p (rtx sym) (extract:MODE (mult (reg) (MULT_IMM)) (EXTRACT_IMM) (const_int 0)). */ bool -aarch64_is_extend_from_extract (machine_mode mode, rtx mult_imm, +aarch64_is_extend_from_extract (scalar_int_mode mode, rtx mult_imm, rtx extract_imm) { HOST_WIDE_INT mult_val, extract_val; @@ -1744,7 +1744,8 @@ aarch64_force_temporary (machine_mode mode, rtx x, rtx value) static rtx -aarch64_add_offset (machine_mode mode, rtx temp, rtx reg, HOST_WIDE_INT offset) +aarch64_add_offset (scalar_int_mode mode, rtx temp, rtx reg, + HOST_WIDE_INT offset) { if (!aarch64_plus_immediate (GEN_INT (offset), mode)) { @@ -1762,7 +1763,7 @@ aarch64_add_offset (machine_mode mode, rtx temp, rtx reg, HOST_WIDE_INT offset) static int aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate, - machine_mode mode) + scalar_int_mode mode) { int i; unsigned HOST_WIDE_INT val, val2, mask; @@ -1868,9 +1869,11 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) gcc_assert (mode == SImode || mode == DImode); /* Check on what type of symbol it is. */ - if (GET_CODE (imm) == SYMBOL_REF - || GET_CODE (imm) == LABEL_REF - || GET_CODE (imm) == CONST) + scalar_int_mode int_mode; + if ((GET_CODE (imm) == SYMBOL_REF + || GET_CODE (imm) == LABEL_REF + || GET_CODE (imm) == CONST) + && is_a <scalar_int_mode> (mode, &int_mode)) { rtx mem, base, offset; enum aarch64_symbol_type sty; @@ -1884,11 +1887,12 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) { case SYMBOL_FORCE_TO_MEM: if (offset != const0_rtx - && targetm.cannot_force_const_mem (mode, imm)) + && targetm.cannot_force_const_mem (int_mode, imm)) { gcc_assert (can_create_pseudo_p ()); - base = aarch64_force_temporary (mode, dest, base); - base = aarch64_add_offset (mode, NULL, base, INTVAL (offset)); + base = aarch64_force_temporary (int_mode, dest, base); + base = aarch64_add_offset (int_mode, NULL, base, + INTVAL (offset)); aarch64_emit_move (dest, base); return; } @@ -1908,8 +1912,8 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) mem = gen_rtx_MEM (ptr_mode, base); } - if (mode != ptr_mode) - mem = gen_rtx_ZERO_EXTEND (mode, mem); + if (int_mode != ptr_mode) + mem = gen_rtx_ZERO_EXTEND (int_mode, mem); emit_insn (gen_rtx_SET (dest, mem)); @@ -1925,8 +1929,9 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) if (offset != const0_rtx) { gcc_assert(can_create_pseudo_p ()); - base = aarch64_force_temporary (mode, dest, base); - base = aarch64_add_offset (mode, NULL, base, INTVAL (offset)); + base = aarch64_force_temporary (int_mode, dest, base); + base = aarch64_add_offset (int_mode, NULL, base, + INTVAL (offset)); aarch64_emit_move (dest, base); return; } @@ -1960,7 +1965,8 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) return; } - aarch64_internal_mov_immediate (dest, imm, true, GET_MODE (dest)); + aarch64_internal_mov_immediate (dest, imm, true, + as_a <scalar_int_mode> (mode)); } /* Add DELTA to REGNUM in mode MODE. SCRATCHREG can be used to hold a @@ -1976,9 +1982,9 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm) large immediate). */ static void -aarch64_add_constant_internal (machine_mode mode, int regnum, int scratchreg, - HOST_WIDE_INT delta, bool frame_related_p, - bool emit_move_imm) +aarch64_add_constant_internal (scalar_int_mode mode, int regnum, + int scratchreg, HOST_WIDE_INT delta, + bool frame_related_p, bool emit_move_imm) { HOST_WIDE_INT mdelta = abs_hwi (delta); rtx this_rtx = gen_rtx_REG (mode, regnum); @@ -2025,7 +2031,7 @@ aarch64_add_constant_internal (machine_mode mode, int regnum, int scratchreg, } static inline void -aarch64_add_constant (machine_mode mode, int regnum, int scratchreg, +aarch64_add_constant (scalar_int_mode mode, int regnum, int scratchreg, HOST_WIDE_INT delta) { aarch64_add_constant_internal (mode, regnum, scratchreg, delta, false, true); @@ -3854,7 +3860,7 @@ aarch64_uimm12_shift (HOST_WIDE_INT val) /* Return true if val is an immediate that can be loaded into a register by a MOVZ instruction. */ static bool -aarch64_movw_imm (HOST_WIDE_INT val, machine_mode mode) +aarch64_movw_imm (HOST_WIDE_INT val, scalar_int_mode mode) { if (GET_MODE_SIZE (mode) > 4) { @@ -3956,7 +3962,7 @@ aarch64_and_split_imm2 (HOST_WIDE_INT val_in) /* Return true if VAL_IN is a valid 'and' bitmask immediate. */ bool -aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, machine_mode mode) +aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, scalar_int_mode mode) { if (aarch64_bitmask_imm (val_in, mode)) return false; @@ -3972,7 +3978,7 @@ aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, machine_mode mode) /* Return true if val is an immediate that can be loaded into a register in a single instruction. */ bool -aarch64_move_imm (HOST_WIDE_INT val, machine_mode mode) +aarch64_move_imm (HOST_WIDE_INT val, scalar_int_mode mode) { if (aarch64_movw_imm (val, mode) || aarch64_movw_imm (~val, mode)) return 1; @@ -5800,7 +5806,8 @@ aarch64_output_casesi (rtx *operands) gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); - index = exact_log2 (GET_MODE_SIZE (GET_MODE (diff_vec))); + scalar_int_mode mode = as_a <scalar_int_mode> (GET_MODE (diff_vec)); + index = exact_log2 (GET_MODE_SIZE (mode)); gcc_assert (index >= 0 && index <= 3); @@ -5919,13 +5926,17 @@ aarch64_strip_shift (rtx x) static rtx aarch64_strip_extend (rtx x) { + scalar_int_mode mode; rtx op = x; + if (!is_a <scalar_int_mode> (GET_MODE (op), &mode)) + return op; + /* Zero and sign extraction of a widened value. */ if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT) && XEXP (op, 2) == const0_rtx && GET_CODE (XEXP (op, 0)) == MULT - && aarch64_is_extend_from_extract (GET_MODE (op), XEXP (XEXP (op, 0), 1), + && aarch64_is_extend_from_extract (mode, XEXP (XEXP (op, 0), 1), XEXP (op, 1))) return XEXP (XEXP (op, 0), 0); @@ -6224,7 +6235,7 @@ aarch64_branch_cost (bool speed_p, bool predictable_p) /* Return true if the RTX X in mode MODE is a zero or sign extract usable in an ADD or SUB (extended register) instruction. */ static bool -aarch64_rtx_arith_op_extract_p (rtx x, machine_mode mode) +aarch64_rtx_arith_op_extract_p (rtx x, scalar_int_mode mode) { /* Catch add with a sign extract. This is add_<optab><mode>_multp2. */ @@ -6468,7 +6479,8 @@ aarch64_extend_bitfield_pattern_p (rtx x) 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) +aarch64_mask_and_shift_for_ubfiz_p (scalar_int_mode mode, rtx mask, + rtx shft_amnt) { return CONST_INT_P (mask) && CONST_INT_P (shft_amnt) && INTVAL (shft_amnt) < GET_MODE_BITSIZE (mode) @@ -6606,8 +6618,10 @@ aarch64_rtx_costs (rtx x, machine_mode mode, int outer ATTRIBUTE_UNUSED, proportionally expensive to the number of instructions required to build that constant. This is true whether we are compiling for SPEED or otherwise. */ + if (!is_a <scalar_int_mode> (mode, &int_mode)) + int_mode = word_mode; *cost = COSTS_N_INSNS (aarch64_internal_mov_immediate - (NULL_RTX, x, false, mode)); + (NULL_RTX, x, false, int_mode)); } return true; @@ -6860,7 +6874,8 @@ cost_minus: } /* Look for SUB (extended register). */ - if (aarch64_rtx_arith_op_extract_p (op1, mode)) + if (is_a <scalar_int_mode> (mode, &int_mode) + && aarch64_rtx_arith_op_extract_p (op1, int_mode)) { if (speed) *cost += extra_cost->alu.extend_arith; @@ -6939,7 +6954,8 @@ cost_plus: *cost += rtx_cost (op1, mode, PLUS, 1, speed); /* Look for ADD (extended register). */ - if (aarch64_rtx_arith_op_extract_p (op0, mode)) + if (is_a <scalar_int_mode> (mode, &int_mode) + && aarch64_rtx_arith_op_extract_p (op0, int_mode)) { if (speed) *cost += extra_cost->alu.extend_arith; @@ -11262,11 +11278,10 @@ aarch64_simd_gen_const_vector_dup (machine_mode mode, int val) /* Check OP is a legal scalar immediate for the MOVI instruction. */ bool -aarch64_simd_scalar_immediate_valid_for_move (rtx op, machine_mode mode) +aarch64_simd_scalar_immediate_valid_for_move (rtx op, scalar_int_mode mode) { machine_mode vmode; - gcc_assert (!VECTOR_MODE_P (mode)); vmode = aarch64_preferred_simd_mode (mode); rtx op_v = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (op)); return aarch64_simd_valid_immediate (op_v, vmode, false, NULL); @@ -12543,12 +12558,10 @@ aarch64_output_simd_mov_immediate (rtx const_vector, } char* -aarch64_output_scalar_simd_mov_immediate (rtx immediate, - machine_mode mode) +aarch64_output_scalar_simd_mov_immediate (rtx immediate, scalar_int_mode mode) { machine_mode vmode; - gcc_assert (!VECTOR_MODE_P (mode)); vmode = aarch64_simd_container_mode (mode, 64); rtx v_op = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (immediate)); return aarch64_output_simd_mov_immediate (v_op, vmode, 64); diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index daa991b..d599c5d 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -108,7 +108,8 @@ (define_predicate "aarch64_logical_and_immediate" (and (match_code "const_int") - (match_test "aarch64_and_bitmask_imm (INTVAL (op), mode)"))) + (match_test "aarch64_and_bitmask_imm (INTVAL (op), + as_a <scalar_int_mode> (mode))"))) (define_predicate "aarch64_shift_imm_si" (and (match_code "const_int")