complex_word_subreg_p (machine_mode outer_mode, rtx reg)
{
machine_mode inner_mode = GET_MODE (reg);
- return (GET_MODE_SIZE (outer_mode) <= UNITS_PER_WORD
- && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD
- && GET_MODE_SIZE (inner_mode) / UNITS_PER_WORD != REG_NREGS (reg));
+ poly_uint64 reg_words = REG_NREGS (reg) * UNITS_PER_WORD;
+ return (known_le (GET_MODE_SIZE (outer_mode), UNITS_PER_WORD)
+ && maybe_gt (GET_MODE_SIZE (inner_mode), UNITS_PER_WORD)
+ && !known_equal_after_align_up (GET_MODE_SIZE (inner_mode),
+ reg_words, UNITS_PER_WORD));
}
/* Return true if X is a SUBREG that will need reloading of its SUBREG_REG
&& REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
|| MEM_P (SUBREG_REG (in)))
&& (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
- || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
+ || (known_le (GET_MODE_SIZE (inmode), UNITS_PER_WORD)
&& is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (in)),
&inner_mode)
&& GET_MODE_SIZE (inner_mode) <= UNITS_PER_WORD
&& LOAD_EXTEND_OP (inner_mode) != UNKNOWN)
|| (WORD_REGISTER_OPERATIONS
&& partial_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
- && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
- ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
- / UNITS_PER_WORD)))))
+ && (known_equal_after_align_down
+ (GET_MODE_SIZE (inmode) - 1,
+ GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1,
+ UNITS_PER_WORD)))))
|| (REG_P (SUBREG_REG (in))
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
/* The case where out is nonzero
&& MEM_P (in))
/* This is supposed to happen only for paradoxical subregs made by
combine.c. (SUBREG (MEM)) isn't supposed to occur other ways. */
- gcc_assert (GET_MODE_SIZE (GET_MODE (in)) <= GET_MODE_SIZE (inmode));
+ gcc_assert (known_le (GET_MODE_SIZE (GET_MODE (in)),
+ GET_MODE_SIZE (inmode)));
inmode = GET_MODE (in);
}
&& (paradoxical_subreg_p (outmode, GET_MODE (SUBREG_REG (out)))
|| (WORD_REGISTER_OPERATIONS
&& partial_subreg_p (outmode, GET_MODE (SUBREG_REG (out)))
- && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
- ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
- / UNITS_PER_WORD)))))
+ && (known_equal_after_align_down
+ (GET_MODE_SIZE (outmode) - 1,
+ GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1,
+ UNITS_PER_WORD)))))
|| (REG_P (SUBREG_REG (out))
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
/* The case of a word mode subreg
is handled differently in the following statement. */
- && ! (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
- && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
- > UNITS_PER_WORD))
+ && ! (known_le (GET_MODE_SIZE (outmode), UNITS_PER_WORD)
+ && maybe_gt (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))),
+ UNITS_PER_WORD))
&& !targetm.hard_regno_mode_ok (subreg_regno (out), outmode))
|| (secondary_reload_class (0, rclass, outmode, out) != NO_REGS
&& (secondary_reload_class (0, rclass, GET_MODE (SUBREG_REG (out)),
outloc = &SUBREG_REG (out);
out = *outloc;
gcc_assert (WORD_REGISTER_OPERATIONS || !MEM_P (out)
- || GET_MODE_SIZE (GET_MODE (out))
- <= GET_MODE_SIZE (outmode));
+ || known_le (GET_MODE_SIZE (GET_MODE (out)),
+ GET_MODE_SIZE (outmode)));
outmode = GET_MODE (out);
}
What's going on here. */
&& (in != out
|| (GET_CODE (in) == SUBREG
- && (((GET_MODE_SIZE (GET_MODE (in)) + (UNITS_PER_WORD - 1))
- / UNITS_PER_WORD)
- == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
+ && (known_equal_after_align_up
+ (GET_MODE_SIZE (GET_MODE (in)),
+ GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))),
+ UNITS_PER_WORD))))
/* Make sure the operand fits in the reg that dies. */
- && (GET_MODE_SIZE (rel_mode)
- <= GET_MODE_SIZE (GET_MODE (XEXP (note, 0))))
+ && known_le (GET_MODE_SIZE (rel_mode),
+ GET_MODE_SIZE (GET_MODE (XEXP (note, 0))))
&& targetm.hard_regno_mode_ok (regno, inmode)
&& targetm.hard_regno_mode_ok (regno, outmode))
{
/* If operands exceed a word, we can't use either of them
unless they have the same size. */
- if (GET_MODE_SIZE (outmode) != GET_MODE_SIZE (inmode)
- && (GET_MODE_SIZE (outmode) > UNITS_PER_WORD
- || GET_MODE_SIZE (inmode) > UNITS_PER_WORD))
+ if (maybe_ne (GET_MODE_SIZE (outmode), GET_MODE_SIZE (inmode))
+ && (maybe_gt (GET_MODE_SIZE (outmode), UNITS_PER_WORD)
+ || maybe_gt (GET_MODE_SIZE (inmode), UNITS_PER_WORD)))
return 0;
/* Note that {in,out}_offset are needed only when 'in' or 'out'
if (replace
&& MEM_P (op)
&& REG_P (reg)
- && (GET_MODE_SIZE (GET_MODE (reg))
- >= GET_MODE_SIZE (GET_MODE (op)))
+ && known_ge (GET_MODE_SIZE (GET_MODE (reg)),
+ GET_MODE_SIZE (GET_MODE (op)))
&& reg_equiv_constant (REGNO (reg)) == 0)
set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
insn),
&& (paradoxical_subreg_p
(operand_mode[i], GET_MODE (operand)))))
|| BYTES_BIG_ENDIAN
- || ((GET_MODE_SIZE (operand_mode[i])
- <= UNITS_PER_WORD)
+ || (known_le (GET_MODE_SIZE (operand_mode[i]),
+ UNITS_PER_WORD)
&& (is_a <scalar_int_mode>
(GET_MODE (operand), &inner_mode))
&& (GET_MODE_SIZE (inner_mode)
if (! win && ! did_match
&& this_alternative[i] != NO_REGS
- && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
+ && known_le (GET_MODE_SIZE (operand_mode[i]), UNITS_PER_WORD)
&& reg_class_size [(int) preferred_class[i]] > 0
&& ! small_register_class_p (preferred_class[i]))
{
if (WORD_REGISTER_OPERATIONS
&& partial_subreg_p (outer_mode, inner_mode)
- && ((GET_MODE_SIZE (outer_mode) - 1) / UNITS_PER_WORD
- == (GET_MODE_SIZE (inner_mode) - 1) / UNITS_PER_WORD))
+ && known_equal_after_align_down (GET_MODE_SIZE (outer_mode) - 1,
+ GET_MODE_SIZE (inner_mode) - 1,
+ UNITS_PER_WORD))
return NULL;
/* Since we don't attempt to handle paradoxical subregs, we can just