+2015-02-23 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR target/65153
+ * config/sh/sh.md (movsicc_true+3): Remove peephole.
+ * config/sh/sh-protos.h (replace_n_hard_rtx): Don't declare.
+ * config/sh/sh.c (replace_n_hard_rtx): Remove.
+
2015-02-23 Richard Sandiford <richard.sandiford@arm.com>
PR fortran/63427
signed int, machine_mode);
extern rtx sh_dwarf_register_span (rtx);
-extern rtx replace_n_hard_rtx (rtx, rtx *, int , int);
extern int shmedia_cleanup_truncate (rtx);
extern bool sh_contains_memref_p (rtx);
}
}
-/* Replace any occurrence of FROM(n) in X with TO(n). The function does
- not enter into CONST_DOUBLE for the replace.
-
- Note that copying is not done so X must not be shared unless all copies
- are to be modified.
-
- This is like replace_rtx, except that we operate on N_REPLACEMENTS
- replacements simultaneously - FROM(n) is replacements[n*2] and to(n) is
- replacements[n*2+1] - and that we take mode changes into account.
-
- If a replacement is ambiguous, return NULL_RTX.
-
- If MODIFY is zero, don't modify any rtl in place,
- just return zero or nonzero for failure / success. */
-rtx
-replace_n_hard_rtx (rtx x, rtx *replacements, int n_replacements, int modify)
-{
- int i, j;
- const char *fmt;
-
- /* The following prevents loops occurrence when we change MEM in
- CONST_DOUBLE onto the same CONST_DOUBLE. */
- if (x != NULL_RTX && GET_CODE (x) == CONST_DOUBLE)
- return x;
-
- for (i = n_replacements - 1; i >= 0 ; i--)
- if (x == replacements[i*2] && GET_MODE (x) == GET_MODE (replacements[i*2+1]))
- return replacements[i*2+1];
-
- /* Allow this function to make replacements in EXPR_LISTs. */
- if (x == NULL_RTX)
- return NULL_RTX;
-
- if (GET_CODE (x) == SUBREG)
- {
- rtx new_rtx = replace_n_hard_rtx (SUBREG_REG (x), replacements,
- n_replacements, modify);
-
- if (CONST_INT_P (new_rtx))
- {
- x = simplify_subreg (GET_MODE (x), new_rtx,
- GET_MODE (SUBREG_REG (x)),
- SUBREG_BYTE (x));
- if (! x)
- abort ();
- }
- else if (modify)
- SUBREG_REG (x) = new_rtx;
-
- return x;
- }
- else if (REG_P (x))
- {
- unsigned regno = REGNO (x);
- unsigned nregs = (regno < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
- rtx result = NULL_RTX;
-
- for (i = n_replacements - 1; i >= 0; i--)
- {
- rtx from = replacements[i*2];
- rtx to = replacements[i*2+1];
- unsigned from_regno, from_nregs, to_regno, new_regno;
-
- if (!REG_P (from))
- continue;
- from_regno = REGNO (from);
- from_nregs = (from_regno < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (from_regno, GET_MODE (from)) : 1);
- if (regno < from_regno + from_nregs && regno + nregs > from_regno)
- {
- if (regno < from_regno
- || regno + nregs > from_regno + nregs
- || !REG_P (to)
- || result)
- return NULL_RTX;
- to_regno = REGNO (to);
- if (to_regno < FIRST_PSEUDO_REGISTER)
- {
- new_regno = regno + to_regno - from_regno;
- if ((unsigned) HARD_REGNO_NREGS (new_regno, GET_MODE (x))
- != nregs)
- return NULL_RTX;
- result = gen_rtx_REG (GET_MODE (x), new_regno);
- }
- else if (GET_MODE (x) <= GET_MODE (to))
- result = gen_lowpart_common (GET_MODE (x), to);
- else
- result = gen_lowpart_SUBREG (GET_MODE (x), to);
- }
- }
- return result ? result : x;
- }
- else if (GET_CODE (x) == ZERO_EXTEND)
- {
- rtx new_rtx = replace_n_hard_rtx (XEXP (x, 0), replacements,
- n_replacements, modify);
-
- if (CONST_INT_P (new_rtx))
- {
- x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
- new_rtx, GET_MODE (XEXP (x, 0)));
- if (! x)
- abort ();
- }
- else if (modify)
- XEXP (x, 0) = new_rtx;
-
- return x;
- }
-
- fmt = GET_RTX_FORMAT (GET_CODE (x));
- for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
- {
- rtx new_rtx;
-
- if (fmt[i] == 'e')
- {
- new_rtx = replace_n_hard_rtx (XEXP (x, i), replacements,
- n_replacements, modify);
- if (!new_rtx)
- return NULL_RTX;
- if (modify)
- XEXP (x, i) = new_rtx;
- }
- else if (fmt[i] == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- {
- new_rtx = replace_n_hard_rtx (XVECEXP (x, i, j), replacements,
- n_replacements, modify);
- if (!new_rtx)
- return NULL_RTX;
- if (modify)
- XVECEXP (x, i, j) = new_rtx;
- }
- }
-
- return x;
-}
-
rtx
sh_gen_truncate (machine_mode mode, rtx x, int need_sign_ext)
{
replace_rtx (operands[4], operands[0], operands[1]);
})
-(define_peephole2
- [(set (match_operand 0 "any_register_operand" "")
- (match_operand 1 "any_register_operand" ""))
- (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
- (set (match_operand 4 "" "") (match_operand 5 "" ""))]
- "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
- <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
- && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
- && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
- && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
- && ! reg_overlap_mentioned_p (operands[0], operands[3])
- && ! reg_overlap_mentioned_p (operands[2], operands[0])
- && ! reg_overlap_mentioned_p (operands[0], operands[1])
- && (REGNO_REG_CLASS (REGNO (operands[0]))
- == REGNO_REG_CLASS (REGNO (operands[2])))
- && (REGNO_REG_CLASS (REGNO (operands[1]))
- == REGNO_REG_CLASS (REGNO (operands[0])))"
- [(set (match_dup 0) (match_dup 3))
- (set (match_dup 4) (match_dup 5))]
-{
- rtx set1, set2;
- rtx_insn *insn1, *insn2;
- rtx replacements[4];
-
- /* We want to replace occurrences of operands[0] with operands[1] and
- operands[2] with operands[0] in operands[4]/operands[5].
- Doing just two replace_rtx calls naively would result in the second
- replacement undoing all that the first did if operands[1] and operands[2]
- are identical, so we must do this simultaneously. */
- replacements[0] = operands[0];
- replacements[1] = operands[1];
- replacements[2] = operands[2];
- replacements[3] = operands[0];
- if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
- || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
- || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
- FAIL;
-
- operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
- replace_n_hard_rtx (operands[4], replacements, 2, 1);
- operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
- /* The operands array is aliased to recog_data.operand, which gets
- clobbered by extract_insn, so finish with it now. */
- set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
- set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
- /* ??? The last insn might be a jump insn, but the generic peephole2 code
- always uses emit_insn. */
- /* Check that we don't violate matching constraints or earlyclobbers. */
- basic_block bb = BLOCK_FOR_INSN (peep2_next_insn (2));
- insn1 = emit_insn (set1);
- extract_insn (insn1);
- if (! constrain_operands (1, get_preferred_alternatives (insn1, bb)))
- goto failure;
- insn2 = emit (set2);
- if (GET_CODE (insn2) == BARRIER)
- goto failure;
- extract_insn (insn2);
- if (! constrain_operands (1, get_preferred_alternatives (insn2, bb)))
- {
- failure:
- std::swap (replacements[0], replacements[1]);
- std::swap (replacements[2], replacements[3]);
- replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
- replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
- replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
- FAIL;
- }
- DONE;
-})
-
;; The register allocator is rather clumsy in handling multi-way conditional
;; moves, so allow the combiner to make them, and we split them up after
;; reload. */