aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2016-08-26 10:22:08 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2016-08-26 10:22:08 +0000
commit5791f55d02239dc7172884f9d5143632b8ca602d (patch)
tree7a517b2ff4d5f706203ba4354eb725581b88fe53 /gcc
parent209ca542cadd7ae7dc174bc74e066ed1de246672 (diff)
downloadgcc-5791f55d02239dc7172884f9d5143632b8ca602d.zip
gcc-5791f55d02239dc7172884f9d5143632b8ca602d.tar.gz
gcc-5791f55d02239dc7172884f9d5143632b8ca602d.tar.bz2
[ARM] Refactor MOVW/MOVT fusion logic to allow extension
* config/arm/arm.c (arm_sets_movw_movt_fusible_p): New function. (aarch_macro_fusion_pair_p): Use above to avoid early return. From-SVN: r239771
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/arm/arm.c89
2 files changed, 55 insertions, 39 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d4360f7..9c82deb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2016-08-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.c (arm_sets_movw_movt_fusible_p): New function.
+ (aarch_macro_fusion_pair_p): Use above to avoid early return.
+
2016-08-26 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
Martin Jambhor <mjambor@suse.cz>
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index c775807..43a832e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -29914,11 +29914,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);
@@ -29936,45 +29982,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;
}