This patch add predicate for storewb_pair/loadwb_pair, because aarch64 register pair push and pop instructions only accept constant offset within certain range.
OK for trunk? Thanks. gcc/ChangeLog: 2014-06-12 Renlin Li <renlin...@arm.com> * config/aarch64/aarch64.c (offset_7bit_signed_scaled_p): Rename to 'aarch64_offset_7bit_signed_scaled_p', remove static and use it . * config/aarch64/aarch64-protos.h (aarch64_offset_7bit_signed_scaled_p): New Declaration. * config/aarch64/predicates.md (aarch64_mem_pair_offset): New predicate. * config/aarch64/aarch64.md (loadwb_pair): Use aarch64_mem_pair_offset. (storewb_pair): Likewise.
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 68d488d..d39ecc5 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -193,6 +193,7 @@ bool aarch64_modes_tieable_p (enum machine_mode mode1, bool aarch64_move_imm (HOST_WIDE_INT, enum machine_mode); bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context, enum machine_mode); +bool aarch64_offset_7bit_signed_scaled_p (enum machine_mode, HOST_WIDE_INT); char *aarch64_output_scalar_simd_mov_immediate (rtx, enum machine_mode); char *aarch64_output_simd_mov_immediate (rtx, enum machine_mode, unsigned); bool aarch64_pad_arg_upward (enum machine_mode, const_tree); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index f69457a..192caf4 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -3122,8 +3122,9 @@ aarch64_classify_index (struct aarch64_address_info *info, rtx x, return false; } -static inline bool -offset_7bit_signed_scaled_p (enum machine_mode mode, HOST_WIDE_INT offset) +bool +aarch64_offset_7bit_signed_scaled_p (enum machine_mode mode, + HOST_WIDE_INT offset) { return (offset >= -64 * GET_MODE_SIZE (mode) && offset < 64 * GET_MODE_SIZE (mode) @@ -3195,12 +3196,12 @@ aarch64_classify_address (struct aarch64_address_info *info, We conservatively require an offset representable in either mode. */ if (mode == TImode || mode == TFmode) - return (offset_7bit_signed_scaled_p (mode, offset) + return (aarch64_offset_7bit_signed_scaled_p (mode, offset) && offset_9bit_signed_unscaled_p (mode, offset)); if (outer_code == PARALLEL) return ((GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8) - && offset_7bit_signed_scaled_p (mode, offset)); + && aarch64_offset_7bit_signed_scaled_p (mode, offset)); else return (offset_9bit_signed_unscaled_p (mode, offset) || offset_12bit_unsigned_scaled_p (mode, offset)); @@ -3255,12 +3256,12 @@ aarch64_classify_address (struct aarch64_address_info *info, We conservatively require an offset representable in either mode. */ if (mode == TImode || mode == TFmode) - return (offset_7bit_signed_scaled_p (mode, offset) + return (aarch64_offset_7bit_signed_scaled_p (mode, offset) && offset_9bit_signed_unscaled_p (mode, offset)); if (outer_code == PARALLEL) return ((GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8) - && offset_7bit_signed_scaled_p (mode, offset)); + && aarch64_offset_7bit_signed_scaled_p (mode, offset)); else return offset_9bit_signed_unscaled_p (mode, offset); } diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index fec2ea8..e15747f 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -949,7 +949,7 @@ [(parallel [(set (match_operand:P 0 "register_operand" "=k") (plus:P (match_operand:P 1 "register_operand" "0") - (match_operand:P 4 "const_int_operand" "n"))) + (match_operand:P 4 "aarch64_mem_pair_offset" "n"))) (set (match_operand:GPI 2 "register_operand" "=r") (mem:GPI (plus:P (match_dup 1) (match_dup 4)))) @@ -967,7 +967,7 @@ [(parallel [(set (match_operand:P 0 "register_operand" "=&k") (plus:P (match_operand:P 1 "register_operand" "0") - (match_operand:P 4 "const_int_operand" "n"))) + (match_operand:P 4 "aarch64_mem_pair_offset" "n"))) (set (mem:GPI (plus:P (match_dup 0) (match_dup 4))) (match_operand:GPI 2 "register_operand" "r")) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 2702a3c..478de11 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -123,6 +123,10 @@ (match_test "INTVAL (op) != 0 && (unsigned) exact_log2 (INTVAL (op)) < 64"))) +(define_predicate "aarch64_mem_pair_offset" + (and (match_code "const_int") + (match_test "aarch64_offset_7bit_signed_scaled_p (mode, INTVAL (op))"))) + (define_predicate "aarch64_mem_pair_operand" (and (match_code "mem") (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL,