return;
}
+/* Rewrite move insn into subtract of 0 if the condition codes will
+ be useful in next conditional jump insn. */
+
+static void
+thumb1_reorg (void)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ rtx set, dest, src;
+ rtx pat, op0;
+ rtx prev, insn = BB_END (bb);
+
+ while (insn != BB_HEAD (bb) && DEBUG_INSN_P (insn))
+ insn = PREV_INSN (insn);
+
+ /* Find the last cbranchsi4_insn in basic block BB. */
+ if (INSN_CODE (insn) != CODE_FOR_cbranchsi4_insn)
+ continue;
+
+ /* Find the first non-note insn before INSN in basic block BB. */
+ gcc_assert (insn != BB_HEAD (bb));
+ prev = PREV_INSN (insn);
+ while (prev != BB_HEAD (bb) && (NOTE_P (prev) || DEBUG_INSN_P (prev)))
+ prev = PREV_INSN (prev);
+
+ set = single_set (prev);
+ if (!set)
+ continue;
+
+ dest = SET_DEST (set);
+ src = SET_SRC (set);
+ if (!low_register_operand (dest, SImode)
+ || !low_register_operand (src, SImode))
+ continue;
+
+ pat = PATTERN (insn);
+ op0 = XEXP (XEXP (SET_SRC (pat), 0), 0);
+ /* Rewrite move into subtract of 0 if its operand is compared with ZERO
+ in INSN. Don't need to check dest since cprop_hardreg pass propagates
+ src into INSN. */
+ if (REGNO (op0) == REGNO (src))
+ {
+ dest = copy_rtx (dest);
+ src = copy_rtx (src);
+ src = gen_rtx_MINUS (SImode, src, const0_rtx);
+ PATTERN (prev) = gen_rtx_SET (VOIDmode, dest, src);
+ INSN_CODE (prev) = -1;
+ /* Set test register in INSN to dest. */
+ XEXP (XEXP (SET_SRC (pat), 0), 0) = copy_rtx (dest);
+ INSN_CODE (insn) = -1;
+ }
+ }
+}
+
/* Convert instructions to their cc-clobbering variant if possible, since
that allows us to use smaller encodings. */
HOST_WIDE_INT address = 0;
Mfix * fix;
- if (TARGET_THUMB2)
+ if (TARGET_THUMB1)
+ thumb1_reorg ();
+ else if (TARGET_THUMB2)
thumb2_reorg ();
/* Ensure all insns that must be split have been split at this point.
if (src1 == const0_rtx)
cfun->machine->thumb1_cc_mode = CCmode;
}
+ else if (REG_P (SET_DEST (set)) && REG_P (SET_SRC (set)))
+ {
+ /* Record the src register operand instead of dest because
+ cprop_hardreg pass propagates src. */
+ cfun->machine->thumb1_cc_op0 = SET_SRC (set);
+ }
}
else if (conds != CONDS_NOCOND)
cfun->machine->thumb1_cc_insn = NULL_RTX;
(const_int 8))))]
)
-;; Two peepholes to generate subtract of 0 instead of a move if the
-;; condition codes will be useful.
-(define_peephole2
- [(set (match_operand:SI 0 "low_register_operand" "")
- (match_operand:SI 1 "low_register_operand" ""))
- (set (pc)
- (if_then_else (match_operator 2 "arm_comparison_operator"
- [(match_dup 1) (const_int 0)])
- (label_ref (match_operand 3 "" ""))
- (pc)))]
- "TARGET_THUMB1"
- [(set (match_dup 0) (minus:SI (match_dup 1) (const_int 0)))
- (set (pc)
- (if_then_else (match_op_dup 2 [(match_dup 0) (const_int 0)])
- (label_ref (match_dup 3))
- (pc)))]
- "")
-
-;; Sigh! This variant shouldn't be needed, but combine often fails to
-;; merge cases like this because the op1 is a hard register in
-;; arm_class_likely_spilled_p.
-(define_peephole2
- [(set (match_operand:SI 0 "low_register_operand" "")
- (match_operand:SI 1 "low_register_operand" ""))
- (set (pc)
- (if_then_else (match_operator 2 "arm_comparison_operator"
- [(match_dup 0) (const_int 0)])
- (label_ref (match_operand 3 "" ""))
- (pc)))]
- "TARGET_THUMB1"
- [(set (match_dup 0) (minus:SI (match_dup 1) (const_int 0)))
- (set (pc)
- (if_then_else (match_op_dup 2 [(match_dup 0) (const_int 0)])
- (label_ref (match_dup 3))
- (pc)))]
- "")
-
(define_insn "*negated_cbranchsi4"
[(set (pc)
(if_then_else