From b52a5acf8da6ba25c9b0eef20c9fe6b59dd68128 Mon Sep 17 00:00:00 2001 From: Yvan Roux Date: Sun, 4 Sep 2016 14:30:29 +0200 Subject: gcc/ Backport from trunk r239771. 2016-08-26 Kyrylo Tkachov * config/arm/arm.c (arm_sets_movw_movt_fusible_p): New function. (aarch_macro_fusion_pair_p): Use above to avoid early return. Change-Id: I07948bb47d410afc9b63578a676371eef3fa8ba0 --- gcc/config/arm/arm.c | 89 +++++++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 39 deletions(-) (limited to 'gcc/config/arm/arm.c') diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 7567c5ebcdb..a570e06b11a 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -29846,11 +29846,57 @@ arm_macro_fusion_p (void) return current_tune->fusible_ops != tune_params::FUSE_NOTHING; } +/* Return true if the two back-to-back sets PREV_SET, CURR_SET are suitable + for MOVW / MOVT macro fusion. */ + +static bool +arm_sets_movw_movt_fusible_p (rtx prev_set, rtx curr_set) +{ + /* We are trying to fuse + movw imm / movt imm + instructions as a group that gets scheduled together. */ + + rtx set_dest = SET_DEST (curr_set); + + if (GET_MODE (set_dest) != SImode) + return false; + + /* We are trying to match: + prev (movw) == (set (reg r0) (const_int imm16)) + curr (movt) == (set (zero_extract (reg r0) + (const_int 16) + (const_int 16)) + (const_int imm16_1)) + or + prev (movw) == (set (reg r1) + (high (symbol_ref ("SYM")))) + curr (movt) == (set (reg r0) + (lo_sum (reg r1) + (symbol_ref ("SYM")))) */ + + if (GET_CODE (set_dest) == ZERO_EXTRACT) + { + if (CONST_INT_P (SET_SRC (curr_set)) + && CONST_INT_P (SET_SRC (prev_set)) + && REG_P (XEXP (set_dest, 0)) + && REG_P (SET_DEST (prev_set)) + && REGNO (XEXP (set_dest, 0)) == REGNO (SET_DEST (prev_set))) + return true; + + } + else if (GET_CODE (SET_SRC (curr_set)) == LO_SUM + && REG_P (SET_DEST (curr_set)) + && REG_P (SET_DEST (prev_set)) + && GET_CODE (SET_SRC (prev_set)) == HIGH + && REGNO (SET_DEST (curr_set)) == REGNO (SET_DEST (prev_set))) + return true; + + return false; +} static bool aarch_macro_fusion_pair_p (rtx_insn* prev, rtx_insn* curr) { - rtx set_dest; rtx prev_set = single_set (prev); rtx curr_set = single_set (curr); @@ -29868,45 +29914,10 @@ aarch_macro_fusion_pair_p (rtx_insn* prev, rtx_insn* curr) && aarch_crypto_can_dual_issue (prev, curr)) return true; - if (current_tune->fusible_ops & tune_params::FUSE_MOVW_MOVT) - { - /* We are trying to fuse - movw imm / movt imm - instructions as a group that gets scheduled together. */ - - set_dest = SET_DEST (curr_set); - - if (GET_MODE (set_dest) != SImode) - return false; + if (current_tune->fusible_ops & tune_params::FUSE_MOVW_MOVT + && arm_sets_movw_movt_fusible_p (prev_set, curr_set)) + return true; - /* We are trying to match: - prev (movw) == (set (reg r0) (const_int imm16)) - curr (movt) == (set (zero_extract (reg r0) - (const_int 16) - (const_int 16)) - (const_int imm16_1)) - or - prev (movw) == (set (reg r1) - (high (symbol_ref ("SYM")))) - curr (movt) == (set (reg r0) - (lo_sum (reg r1) - (symbol_ref ("SYM")))) */ - if (GET_CODE (set_dest) == ZERO_EXTRACT) - { - if (CONST_INT_P (SET_SRC (curr_set)) - && CONST_INT_P (SET_SRC (prev_set)) - && REG_P (XEXP (set_dest, 0)) - && REG_P (SET_DEST (prev_set)) - && REGNO (XEXP (set_dest, 0)) == REGNO (SET_DEST (prev_set))) - return true; - } - else if (GET_CODE (SET_SRC (curr_set)) == LO_SUM - && REG_P (SET_DEST (curr_set)) - && REG_P (SET_DEST (prev_set)) - && GET_CODE (SET_SRC (prev_set)) == HIGH - && REGNO (SET_DEST (curr_set)) == REGNO (SET_DEST (prev_set))) - return true; - } return false; } -- cgit v1.2.3