+2017-10-26 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * caller-save.c (mark_referenced_regs): Use read_modify_subreg_p.
+ * combine.c (find_single_use_1): Likewise.
+ (expand_field_assignment): Likewise.
+ (move_deaths): Likewise.
+ * lra-constraints.c (simplify_operand_subreg): Likewise.
+ (curr_insn_transform): Likewise.
+ * lra.c (collect_non_operand_hard_regs): Likewise.
+ (add_regs_to_insn_regno_info): Likewise.
+ * rtlanal.c (reg_referenced_p): Likewise.
+ (covers_regno_no_parallel_p): Likewise.
+
2017-10-26 Richard Sandiford <richard.sandiford@linaro.org>
* wide-int-print.cc (print_hex): Loop based on extract_uhwi.
/* If we're setting only part of a multi-word register,
we shall mark it as referenced, because the words
that are not being set should be restored. */
- && ((GET_MODE_SIZE (GET_MODE (*loc))
- >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (*loc))))
- || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (*loc)))
- <= UNITS_PER_WORD))))
+ && !read_modify_subreg_p (*loc)))
return;
}
if (code == MEM || code == SUBREG)
&& !REG_P (SET_DEST (x))
&& ! (GET_CODE (SET_DEST (x)) == SUBREG
&& REG_P (SUBREG_REG (SET_DEST (x)))
- && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
- == ((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
+ && !read_modify_subreg_p (SET_DEST (x))))
break;
return find_single_use_1 (dest, &SET_SRC (x));
}
}
- /* A SUBREG between two modes that occupy the same numbers of words
- can be done by moving the SUBREG to the source. */
+ /* If the destination is a subreg that overwrites the whole of the inner
+ register, we can move the subreg to the source. */
else if (GET_CODE (SET_DEST (x)) == SUBREG
/* We need SUBREGs to compute nonzero_bits properly. */
&& nonzero_sign_valid
- && (((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
- == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
+ && !read_modify_subreg_p (SET_DEST (x)))
{
x = gen_rtx_SET (SUBREG_REG (SET_DEST (x)),
gen_lowpart
if (GET_CODE (dest) == ZERO_EXTRACT
|| GET_CODE (dest) == STRICT_LOW_PART
|| (GET_CODE (dest) == SUBREG
- && (((GET_MODE_SIZE (GET_MODE (dest))
- + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
- == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
- + UNITS_PER_WORD - 1) / UNITS_PER_WORD))))
+ && !read_modify_subreg_p (dest)))
{
move_deaths (dest, maybe_kill_insn, from_luid, to_insn, pnotes);
return;
bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg));
insert_before = (type != OP_OUT
- || GET_MODE_SIZE (innermode) > GET_MODE_SIZE (mode));
+ || read_modify_subreg_p (operand));
insert_after = (type != OP_IN);
insert_move_for_subreg (insert_before ? &before : NULL,
insert_after ? &after : NULL,
constraints. */
if (type == OP_OUT
&& (curr_static_id->operand[i].strict_low
- || (GET_MODE_SIZE (GET_MODE (reg)) > UNITS_PER_WORD
- && (GET_MODE_SIZE (mode)
- < GET_MODE_SIZE (GET_MODE (reg))))))
+ || read_modify_subreg_p (*loc)))
type = OP_INOUT;
loc = &SUBREG_REG (*loc);
mode = GET_MODE (*loc);
subreg_p = false;
if (code == SUBREG)
{
+ if (read_modify_subreg_p (op))
+ subreg_p = true;
op = SUBREG_REG (op);
code = GET_CODE (op);
if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (op)))
- {
- mode = GET_MODE (op);
- if (GET_MODE_SIZE (mode) > REGMODE_NATURAL_SIZE (mode))
- subreg_p = true;
- }
+ mode = GET_MODE (op);
}
if (REG_P (op))
{
subreg_p = false;
if (GET_CODE (x) == SUBREG)
{
+ if (read_modify_subreg_p (x))
+ subreg_p = true;
x = SUBREG_REG (x);
code = GET_CODE (x);
if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x)))
- {
- mode = GET_MODE (x);
- if (GET_MODE_SIZE (mode) > REGMODE_NATURAL_SIZE (mode))
- subreg_p = true;
- }
+ mode = GET_MODE (x);
}
if (REG_P (x))
{
&& !REG_P (SET_DEST (body))
&& ! (GET_CODE (SET_DEST (body)) == SUBREG
&& REG_P (SUBREG_REG (SET_DEST (body)))
- && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (body))))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
- == ((GET_MODE_SIZE (GET_MODE (SET_DEST (body)))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
+ && !read_modify_subreg_p (SET_DEST (body)))
&& reg_overlap_mentioned_p (x, SET_DEST (body)))
return 1;
return 0;
return 1;
}
-/* Return TRUE iff DEST is a register or subreg of a register and
- doesn't change the number of words of the inner register, and any
- part of the register is TEST_REGNO. */
+/* Return TRUE iff DEST is a register or subreg of a register, is a
+ complete rather than read-modify-write destination, and contains
+ register TEST_REGNO. */
static bool
covers_regno_no_parallel_p (const_rtx dest, unsigned int test_regno)
{
unsigned int regno, endregno;
- if (GET_CODE (dest) == SUBREG
- && (((GET_MODE_SIZE (GET_MODE (dest))
- + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
- == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
- + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
+ if (GET_CODE (dest) == SUBREG && !read_modify_subreg_p (dest))
dest = SUBREG_REG (dest);
if (!REG_P (dest))