little gain doing the checks here. Focus on catching invalid
transformations involving integer constants. */
if (GET_MODE_CLASS (GET_MODE (oldval)) == MODE_INT
- && GET_CODE (newval) == CONST_INT)
+ && CONST_INT_P (newval))
{
/* Sanity check that we're replacing oldval with a CONST_INT
that is a valid sign-extension for the original mode. */
perform this test on oldval instead, checking whether an
invalid replacement took place before we got here. */
gcc_assert (!(GET_CODE (oldval) == SUBREG
- && GET_CODE (SUBREG_REG (oldval)) == CONST_INT));
+ && CONST_INT_P (SUBREG_REG (oldval))));
gcc_assert (!(GET_CODE (oldval) == ZERO_EXTEND
- && GET_CODE (XEXP (oldval, 0)) == CONST_INT));
+ && CONST_INT_P (XEXP (oldval, 0))));
}
if (undobuf.frees)
tree arg;
bool strictly_local = false;
- if (!targetm.calls.promote_function_args (TREE_TYPE (cfun->decl)))
- return;
-
for (arg = DECL_ARGUMENTS (current_function_decl); arg;
arg = TREE_CHAIN (arg))
{
/* The mode and signedness of the argument as it is actually passed,
after any TARGET_PROMOTE_FUNCTION_ARGS-driven ABI promotions. */
- mode3 = promote_mode (DECL_ARG_TYPE (arg), mode2, &uns3, 1);
+ mode3 = promote_function_mode (DECL_ARG_TYPE (arg), mode2, &uns3,
+ TREE_TYPE (cfun->decl), 0);
/* The mode of the register in which the argument is being passed. */
mode4 = GET_MODE (reg);
instead of this kludge. */
if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD
- && GET_CODE (src) == CONST_INT
+ && CONST_INT_P (src)
&& INTVAL (src) > 0
&& 0 != (INTVAL (src)
& ((HOST_WIDE_INT) 1
return 1;
case MULT:
- return ! (GET_CODE (XEXP (x, 1)) == CONST_INT
+ return ! (CONST_INT_P (XEXP (x, 1))
&& exact_log2 (INTVAL (XEXP (x, 1))) >= 0);
default:
if (BINARY_P (x))
/* Reset the hard register usage information. */
CLEAR_HARD_REG_SET (newpat_used_regs);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ if (i1)
+ fprintf (dump_file, "\nTrying %d, %d -> %d:\n",
+ INSN_UID (i1), INSN_UID (i2), INSN_UID (i3));
+ else
+ fprintf (dump_file, "\nTrying %d -> %d:\n",
+ INSN_UID (i2), INSN_UID (i3));
+ }
+
/* If I1 and I2 both feed I3, they can be in any order. To simplify the
code below, set I1 to be the earlier of the two insns. */
if (i1 && DF_INSN_LUID (i1) > DF_INSN_LUID (i2))
constant. */
if (i1 == 0
&& (temp = single_set (i2)) != 0
- && (GET_CODE (SET_SRC (temp)) == CONST_INT
+ && (CONST_INT_P (SET_SRC (temp))
|| GET_CODE (SET_SRC (temp)) == CONST_DOUBLE)
&& GET_CODE (PATTERN (i3)) == SET
- && (GET_CODE (SET_SRC (PATTERN (i3))) == CONST_INT
+ && (CONST_INT_P (SET_SRC (PATTERN (i3)))
|| GET_CODE (SET_SRC (PATTERN (i3))) == CONST_DOUBLE)
&& reg_subword_p (SET_DEST (PATTERN (i3)), SET_DEST (temp)))
{
if (GET_CODE (dest) == ZERO_EXTRACT)
{
- if (GET_CODE (XEXP (dest, 1)) == CONST_INT
- && GET_CODE (XEXP (dest, 2)) == CONST_INT)
+ if (CONST_INT_P (XEXP (dest, 1))
+ && CONST_INT_P (XEXP (dest, 2)))
{
width = INTVAL (XEXP (dest, 1));
offset = INTVAL (XEXP (dest, 2));
rtx inner = SET_SRC (PATTERN (i3));
rtx outer = SET_SRC (temp);
- if (GET_CODE (outer) == CONST_INT)
+ if (CONST_INT_P (outer))
{
olo = INTVAL (outer);
ohi = olo < 0 ? -1 : 0;
ohi = CONST_DOUBLE_HIGH (outer);
}
- if (GET_CODE (inner) == CONST_INT)
+ if (CONST_INT_P (inner))
{
ilo = INTVAL (inner);
ihi = ilo < 0 ? -1 : 0;
an ASHIFT. This can occur if it was inside a PLUS and hence
appeared to be a memory address. This is a kludge. */
if (split_code == MULT
- && GET_CODE (XEXP (*split, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (*split, 1))
&& INTVAL (XEXP (*split, 1)) > 0
&& (i = exact_log2 (INTVAL (XEXP (*split, 1)))) >= 0)
{
the first pseudo-reg (one of the virtual regs) as a placeholder;
it will not remain in the result. */
if (GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1))
&& ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
{
rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
&& (GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0)))
<= HOST_BITS_PER_WIDE_INT)
- && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT
- && GET_CODE (XEXP (SET_DEST (x), 2)) == CONST_INT
- && GET_CODE (SET_SRC (x)) == CONST_INT
+ && CONST_INT_P (XEXP (SET_DEST (x), 1))
+ && CONST_INT_P (XEXP (SET_DEST (x), 2))
+ && CONST_INT_P (SET_SRC (x))
&& ((INTVAL (XEXP (SET_DEST (x), 1))
+ INTVAL (XEXP (SET_DEST (x), 2)))
<= GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0))))
this is no worse, but if it took more than one insn, it will
be better. */
- if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (SET_SRC (x), 1))
&& REG_P (XEXP (SET_SRC (x), 0))
&& (pos = exact_log2 (INTVAL (XEXP (SET_SRC (x), 1)))) >= 7
&& REG_P (SET_DEST (x))
case SIGN_EXTRACT:
case ZERO_EXTRACT:
- if (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
- && GET_CODE (XEXP (SET_SRC (x), 2)) == CONST_INT)
+ if (CONST_INT_P (XEXP (SET_SRC (x), 1))
+ && CONST_INT_P (XEXP (SET_SRC (x), 2)))
{
inner = XEXP (SET_SRC (x), 0);
len = INTVAL (XEXP (SET_SRC (x), 1));
return new_rtx;
if (GET_CODE (x) == SUBREG
- && (GET_CODE (new_rtx) == CONST_INT
+ && (CONST_INT_P (new_rtx)
|| GET_CODE (new_rtx) == CONST_DOUBLE))
{
enum machine_mode mode = GET_MODE (x);
if (! x)
x = gen_rtx_CLOBBER (mode, const0_rtx);
}
- else if (GET_CODE (new_rtx) == CONST_INT
+ else if (CONST_INT_P (new_rtx)
&& GET_CODE (x) == ZERO_EXTEND)
{
x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
/* Likewise, we can make the negate of a comparison operation
if the result values are - STORE_FLAG_VALUE and zero. */
- else if (GET_CODE (true_rtx) == CONST_INT
+ else if (CONST_INT_P (true_rtx)
&& INTVAL (true_rtx) == - STORE_FLAG_VALUE
&& false_rtx == const0_rtx)
x = simplify_gen_unary (NEG, mode,
mode, VOIDmode,
cond, cop1),
mode);
- else if (GET_CODE (false_rtx) == CONST_INT
+ else if (CONST_INT_P (false_rtx)
&& INTVAL (false_rtx) == - STORE_FLAG_VALUE
&& true_rtx == const0_rtx
&& ((reversed = reversed_comparison_code_parts
(neg (sign_extract X 1 Y)) to (zero_extract X 1 Y). */
if (GET_CODE (temp) == ASHIFTRT
- && GET_CODE (XEXP (temp, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (temp, 1))
&& INTVAL (XEXP (temp, 1)) == GET_MODE_BITSIZE (mode) - 1)
return simplify_shift_const (NULL_RTX, LSHIFTRT, mode, XEXP (temp, 0),
INTVAL (XEXP (temp, 1)));
if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
break;
- if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
- && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
- GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))))
+ if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
SUBST (XEXP (x, 0),
force_to_mode (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
GET_MODE_MASK (mode), 0));
sign_extract. The `and' may be a zero_extend and the two
<c>, -<c> constants may be reversed. */
if (GET_CODE (XEXP (x, 0)) == XOR
- && GET_CODE (XEXP (x, 1)) == CONST_INT
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (x, 1))
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1))
&& INTVAL (XEXP (x, 1)) == -INTVAL (XEXP (XEXP (x, 0), 1))
&& ((i = exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) >= 0
|| (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& ((GET_CODE (XEXP (XEXP (x, 0), 0)) == AND
- && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
&& (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))
== ((HOST_WIDE_INT) 1 << (i + 1)) - 1))
|| (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
/* (minus <foo> (and <foo> (const_int -pow2))) becomes
(and <foo> (const_int pow2-1)) */
if (GET_CODE (XEXP (x, 1)) == AND
- && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (x, 1), 1))
&& exact_log2 (-INTVAL (XEXP (XEXP (x, 1), 1))) >= 0
&& rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
return simplify_and_const_int (NULL_RTX, mode, XEXP (x, 0),
case UDIV:
/* If this is a divide by a power of two, treat it as a shift if
its first operand is a shift. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0
&& (GET_CODE (XEXP (x, 0)) == ASHIFT
|| GET_CODE (XEXP (x, 0)) == LSHIFTRT
case ROTATE:
case ROTATERT:
/* If this is a shift by a constant amount, simplify it. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ if (CONST_INT_P (XEXP (x, 1)))
return simplify_shift_const (x, code, mode, XEXP (x, 0),
INTVAL (XEXP (x, 1)));
&& reversed_comparison_code (cond, NULL) != UNKNOWN
&& (true_rtx == pc_rtx
|| (CONSTANT_P (true_rtx)
- && GET_CODE (false_rtx) != CONST_INT && false_rtx != pc_rtx)
+ && !CONST_INT_P (false_rtx) && false_rtx != pc_rtx)
|| true_rtx == const0_rtx
|| (OBJECT_P (true_rtx) && !OBJECT_P (false_rtx))
|| (GET_CODE (true_rtx) == SUBREG && OBJECT_P (SUBREG_REG (true_rtx))
can actually do this more generally, but it doesn't seem worth it. */
if (true_code == NE && XEXP (cond, 1) == const0_rtx
- && false_rtx == const0_rtx && GET_CODE (true_rtx) == CONST_INT
+ && false_rtx == const0_rtx && CONST_INT_P (true_rtx)
&& ((1 == nonzero_bits (XEXP (cond, 0), mode)
&& (i = exact_log2 (INTVAL (true_rtx))) >= 0)
|| ((num_sign_bit_copies (XEXP (cond, 0), mode)
/* (IF_THEN_ELSE (NE REG 0) (0) (8)) is REG for nonzero_bits (REG) == 8. */
if (true_code == NE && XEXP (cond, 1) == const0_rtx
- && false_rtx == const0_rtx && GET_CODE (true_rtx) == CONST_INT
+ && false_rtx == const0_rtx && CONST_INT_P (true_rtx)
&& GET_MODE (XEXP (cond, 0)) == mode
&& (INTVAL (true_rtx) & GET_MODE_MASK (mode))
== nonzero_bits (XEXP (cond, 0), mode)
/* We can call simplify_and_const_int only if we don't lose
any (sign) bits when converting INTVAL (op1) to
"unsigned HOST_WIDE_INT". */
- if (GET_CODE (op1) == CONST_INT
+ if (CONST_INT_P (op1)
&& (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
|| INTVAL (op1) > 0))
{
Even for a mode that is no wider than a const_int,
we can't win, because we need to sign extend one of its bits through
the rest of it, and we don't know which bit. */
- if (GET_CODE (XEXP (x, 0)) == CONST_INT)
+ if (CONST_INT_P (XEXP (x, 0)))
return x;
/* Return if (subreg:MODE FROM 0) is not a safe replacement for
if (GET_CODE (XEXP (x, 0)) == CLOBBER)
return XEXP (x, 0);
- if (GET_CODE (XEXP (x, 1)) != CONST_INT
- || GET_CODE (XEXP (x, 2)) != CONST_INT
+ if (!CONST_INT_P (XEXP (x, 1))
+ || !CONST_INT_P (XEXP (x, 2))
|| GET_MODE (XEXP (x, 0)) == VOIDmode)
return x;
pos = GEN_INT (subreg_lsb (XEXP (SET_DEST (x), 0)));
}
else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
- && GET_CODE (XEXP (SET_DEST (x), 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (SET_DEST (x), 1)))
{
inner = XEXP (SET_DEST (x), 0);
len = INTVAL (XEXP (SET_DEST (x), 1));
pos = XEXP (SET_DEST (x), 2);
/* A constant position should stay within the width of INNER. */
- if (GET_CODE (pos) == CONST_INT
+ if (CONST_INT_P (pos)
&& INTVAL (pos) + len > GET_MODE_BITSIZE (GET_MODE (inner)))
break;
if (BITS_BIG_ENDIAN)
{
- if (GET_CODE (pos) == CONST_INT)
+ if (CONST_INT_P (pos))
pos = GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner)) - len
- INTVAL (pos));
else if (GET_CODE (pos) == MINUS
- && GET_CODE (XEXP (pos, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (pos, 1))
&& (INTVAL (XEXP (pos, 1))
== GET_MODE_BITSIZE (GET_MODE (inner)) - len))
/* If position is ADJUST - X, new position is X. */
inner = SUBREG_REG (inner);
}
else if (GET_CODE (inner) == ASHIFT
- && GET_CODE (XEXP (inner, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (inner, 1))
&& pos_rtx == 0 && pos == 0
&& len > (unsigned HOST_WIDE_INT) INTVAL (XEXP (inner, 1)))
{
inner_mode = GET_MODE (inner);
- if (pos_rtx && GET_CODE (pos_rtx) == CONST_INT)
+ if (pos_rtx && CONST_INT_P (pos_rtx))
pos = INTVAL (pos_rtx), pos_rtx = 0;
/* See if this can be done without an extraction. We never can if the
if (mode == tmode)
return new_rtx;
- if (GET_CODE (new_rtx) == CONST_INT)
+ if (CONST_INT_P (new_rtx))
return gen_int_mode (INTVAL (new_rtx), mode);
/* If we know that no extraneous bits are set, and that the high
inner = adjust_address_nv (inner, wanted_inner_mode, offset);
}
- /* If INNER is not memory, we can always get it into the proper mode. If we
- are changing its mode, POS must be a constant and smaller than the size
- of the new mode. */
+ /* If INNER is not memory, get it into the proper mode. If we are changing
+ its mode, POS must be a constant and smaller than the size of the new
+ mode. */
else if (!MEM_P (inner))
{
+ /* On the LHS, don't create paradoxical subregs implicitely truncating
+ the register unless TRULY_NOOP_TRUNCATION. */
+ if (in_dest
+ && !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (inner)),
+ GET_MODE_BITSIZE (wanted_inner_mode)))
+ return NULL_RTX;
+
if (GET_MODE (inner) != wanted_inner_mode
&& (pos_rtx != 0
|| orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode)))
- return 0;
+ return NULL_RTX;
if (orig_pos < 0)
- return 0;
+ return NULL_RTX;
inner = force_to_mode (inner, wanted_inner_mode,
pos_rtx
/* This is the shift itself. If it is wide enough, we will return
either the value being shifted if the shift count is equal to
COUNT or a shift for the difference. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) >= count)
return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (x, 0),
INTVAL (XEXP (x, 1)) - count);
case PLUS: case IOR: case XOR: case AND:
/* If we can safely shift this constant and we find the inner shift,
make a new operation. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0
&& (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
return simplify_gen_binary (code, mode, tem,
case ASHIFT:
/* Convert shifts by constants into multiplications if inside
an address. */
- if (in_code == MEM && GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (in_code == MEM && CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
&& INTVAL (XEXP (x, 1)) >= 0)
{
case AND:
/* If the second operand is not a constant, we can't do anything
with it. */
- if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+ if (!CONST_INT_P (XEXP (x, 1)))
break;
/* If the constant is a power of two minus one and the first operand
of bits in M, this is an extraction. */
else if (GET_CODE (XEXP (x, 0)) == ROTATE
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1))
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0
&& i <= INTVAL (XEXP (XEXP (x, 0), 1)))
{
else if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
&& !have_insn_for (LSHIFTRT, mode)
&& have_insn_for (ASHIFTRT, mode)
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1))
&& INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
&& INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
&& mode_width <= HOST_BITS_PER_WIDE_INT)
/* If we have (ashiftrt (ashift foo C1) C2) with C2 >= C1,
this is a SIGN_EXTRACT. */
- if (GET_CODE (rhs) == CONST_INT
+ if (CONST_INT_P (rhs)
&& GET_CODE (lhs) == ASHIFT
- && GET_CODE (XEXP (lhs, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (lhs, 1))
&& INTVAL (rhs) >= INTVAL (XEXP (lhs, 1))
&& INTVAL (rhs) < mode_width)
{
if (!OBJECT_P (lhs)
&& ! (GET_CODE (lhs) == SUBREG
&& (OBJECT_P (SUBREG_REG (lhs))))
- && GET_CODE (rhs) == CONST_INT
+ && CONST_INT_P (rhs)
&& INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
&& INTVAL (rhs) < mode_width
&& (new_rtx = extract_left_shift (lhs, INTVAL (rhs))) != 0)
if (GET_CODE (newer) != SUBREG)
newer = make_compound_operation (newer, in_code);
+ /* force_to_mode can expand compounds. If it just re-expanded the
+ compound use gen_lowpart instead to convert to the desired
+ mode. */
+ if (rtx_equal_p (newer, x))
+ return gen_lowpart (GET_MODE (x), tem);
+
return newer;
}
static rtx
gen_lowpart_or_truncate (enum machine_mode mode, rtx x)
{
- if (GET_MODE_SIZE (GET_MODE (x)) <= GET_MODE_SIZE (mode)
- || TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
- GET_MODE_BITSIZE (GET_MODE (x)))
- || (REG_P (x) && reg_truncated_to_mode (mode, x)))
- return gen_lowpart (mode, x);
- else
- return simplify_gen_unary (TRUNCATE, mode, x, GET_MODE (x));
+ if (!CONST_INT_P (x)
+ && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x))
+ && !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
+ GET_MODE_BITSIZE (GET_MODE (x)))
+ && !(REG_P (x) && reg_truncated_to_mode (mode, x)))
+ {
+ /* Bit-cast X into an integer mode. */
+ if (!SCALAR_INT_MODE_P (GET_MODE (x)))
+ x = gen_lowpart (int_mode_for_mode (GET_MODE (x)), x);
+ x = simplify_gen_unary (TRUNCATE, int_mode_for_mode (mode),
+ x, GET_MODE (x));
+ }
+
+ return gen_lowpart (mode, x);
}
/* See if X can be simplified knowing that we will only refer to it in
/* If X is a CONST_INT, return a new one. Do this here since the
test below will fail. */
- if (GET_CODE (x) == CONST_INT)
+ if (CONST_INT_P (x))
{
if (SCALAR_INT_MODE_P (mode))
return gen_int_mode (INTVAL (x) & mask, mode);
&& (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
return gen_lowpart (mode, x);
- /* The arithmetic simplifications here do the wrong thing on vector modes. */
- if (VECTOR_MODE_P (mode) || VECTOR_MODE_P (GET_MODE (x)))
- return gen_lowpart (mode, x);
+ /* We can ignore the effect of a SUBREG if it narrows the mode or
+ if the constant masks to zero all the bits the mode doesn't have. */
+ if (GET_CODE (x) == SUBREG
+ && subreg_lowpart_p (x)
+ && ((GET_MODE_SIZE (GET_MODE (x))
+ < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+ || (0 == (mask
+ & GET_MODE_MASK (GET_MODE (x))
+ & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
+ return force_to_mode (SUBREG_REG (x), mode, mask, next_select);
+
+ /* The arithmetic simplifications here only work for scalar integer modes. */
+ if (!SCALAR_INT_MODE_P (mode) || !SCALAR_INT_MODE_P (GET_MODE (x)))
+ return gen_lowpart_or_truncate (mode, x);
switch (code)
{
return force_to_mode (x, mode, mask, next_select);
break;
- case SUBREG:
- if (subreg_lowpart_p (x)
- /* We can ignore the effect of this SUBREG if it narrows the mode or
- if the constant masks to zero all the bits the mode doesn't
- have. */
- && ((GET_MODE_SIZE (GET_MODE (x))
- < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
- || (0 == (mask
- & GET_MODE_MASK (GET_MODE (x))
- & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))))))
- return force_to_mode (SUBREG_REG (x), mode, mask, next_select);
- break;
+ case TRUNCATE:
+ /* Similarly for a truncate. */
+ return force_to_mode (XEXP (x, 0), mode, mask, next_select);
case AND:
/* If this is an AND with a constant, convert it into an AND
whose constant is the AND of that constant with MASK. If it
remains an AND of MASK, delete it since it is redundant. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ if (CONST_INT_P (XEXP (x, 1)))
{
x = simplify_and_const_int (x, op_mode, XEXP (x, 0),
mask & INTVAL (XEXP (x, 1)));
is just some low-order bits. If so, and it is MASK, we don't
need it. */
- if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1))
&& ((INTVAL (XEXP (x, 1)) & GET_MODE_MASK (GET_MODE (x)))
== mask))
x = XEXP (x, 0);
constant in the AND is wide enough, this might make a
cheaper constant. */
- if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1))
&& GET_MODE_MASK (GET_MODE (x)) != mask
&& GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT)
{
&& (smask & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
smask |= (HOST_WIDE_INT) -1 << width;
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& exact_log2 (- smask) >= 0
&& (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
&& (INTVAL (XEXP (x, 1)) & ~smask) != 0)
case MINUS:
/* If X is (minus C Y) where C's least set bit is larger than any bit
in the mask, then we may replace with (neg Y). */
- if (GET_CODE (XEXP (x, 0)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 0))
&& (((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 0))
& -INTVAL (XEXP (x, 0))))
> mask))
/* Similarly, if C contains every bit in the fuller_mask, then we may
replace with (not Y). */
- if (GET_CODE (XEXP (x, 0)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 0))
&& ((INTVAL (XEXP (x, 0)) | (HOST_WIDE_INT) fuller_mask)
== INTVAL (XEXP (x, 0))))
{
constant we form is not wider than the mode of X. */
if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1))
&& INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
&& INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
- && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (x, 1))
&& ((INTVAL (XEXP (XEXP (x, 0), 1))
+ floor_log2 (INTVAL (XEXP (x, 1))))
< GET_MODE_BITSIZE (GET_MODE (x)))
/* For most binary operations, just propagate into the operation and
change the mode if we have an operation of that mode. */
- op0 = gen_lowpart_or_truncate (op_mode,
- force_to_mode (XEXP (x, 0), mode, mask,
- next_select));
- op1 = gen_lowpart_or_truncate (op_mode,
- force_to_mode (XEXP (x, 1), mode, mask,
- next_select));
+ op0 = force_to_mode (XEXP (x, 0), mode, mask, next_select);
+ op1 = force_to_mode (XEXP (x, 1), mode, mask, next_select);
+
+ /* If we ended up truncating both operands, truncate the result of the
+ operation instead. */
+ if (GET_CODE (op0) == TRUNCATE
+ && GET_CODE (op1) == TRUNCATE)
+ {
+ op0 = XEXP (op0, 0);
+ op1 = XEXP (op1, 0);
+ }
+
+ op0 = gen_lowpart_or_truncate (op_mode, op0);
+ op1 = gen_lowpart_or_truncate (op_mode, op1);
if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
x = simplify_gen_binary (code, op_mode, op0, op1);
because such a count will have a different meaning in a
wider mode. */
- if (! (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (! (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) >= 0
&& INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (mode))
&& ! (GET_MODE (XEXP (x, 1)) != VOIDmode
/* If the shift count is a constant and we can do arithmetic in
the mode of the shift, refine which bits we need. Otherwise, use the
conservative form of the mask. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) >= 0
&& INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (op_mode)
&& GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT)
this shift constant is valid for the host, and we can do arithmetic
in OP_MODE. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
&& GET_MODE_BITSIZE (op_mode) <= HOST_BITS_PER_WIDE_INT)
{
than a power of two), we can do this with just a shift. */
if (GET_CODE (x) == LSHIFTRT
- && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (x, 1))
/* The shift puts one of the sign bit copies in the least significant
bit. */
&& ((INTVAL (XEXP (x, 1))
those bits, we are requesting a copy of the sign bit and hence can
shift the sign bit to the appropriate location. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) >= 0
+ if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
{
int i;
something that is still a shift. */
if ((GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ASHIFTRT)
- && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) >= 0
&& (INTVAL (XEXP (x, 1))
<= GET_MODE_BITSIZE (GET_MODE (x)) - (floor_log2 (mask) + 1))
in the mode of X, compute where the bits we care about are.
Otherwise, we can't do anything. Don't change the mode of
the shift or propagate MODE into the shift, though. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) >= 0)
{
temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE,
GET_MODE (x), GEN_INT (mask),
XEXP (x, 1));
- if (temp && GET_CODE (temp) == CONST_INT)
+ if (temp && CONST_INT_P (temp))
SUBST (XEXP (x, 0),
force_to_mode (XEXP (x, 0), GET_MODE (x),
INTVAL (temp), next_select));
wider than the mode of X. */
if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1))
&& INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
&& (INTVAL (XEXP (XEXP (x, 0), 1)) + floor_log2 (mask)
< GET_MODE_BITSIZE (GET_MODE (x)))
for a SUBREG. */
if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == ROTATE
- && GET_CODE (XEXP (XEXP (src, 0), 0)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (src, 0), 0))
&& INTVAL (XEXP (XEXP (src, 0), 0)) == -2
&& rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
{
&& (GET_MODE_SIZE (GET_MODE (XEXP (src, 0)))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0)))))
&& GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE
- && GET_CODE (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == CONST_INT
+ && CONST_INT_P (XEXP (SUBREG_REG (XEXP (src, 0)), 0))
&& INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2
&& rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
{
SRC is an AND with all bits of that field set, then we can discard
the AND. */
if (GET_CODE (dest) == ZERO_EXTRACT
- && GET_CODE (XEXP (dest, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (dest, 1))
&& GET_CODE (src) == AND
- && GET_CODE (XEXP (src, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (src, 1)))
{
HOST_WIDE_INT width = INTVAL (XEXP (dest, 1));
unsigned HOST_WIDE_INT and_mask = INTVAL (XEXP (src, 1));
lhs = expand_compound_operation (XEXP (src, 1));
if (GET_CODE (rhs) == AND
- && GET_CODE (XEXP (rhs, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (rhs, 1))
&& rtx_equal_for_field_assignment_p (XEXP (rhs, 0), dest))
c1 = INTVAL (XEXP (rhs, 1)), other = lhs;
else if (GET_CODE (lhs) == AND
- && GET_CODE (XEXP (lhs, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (lhs, 1))
&& rtx_equal_for_field_assignment_p (XEXP (lhs, 0), dest))
c1 = INTVAL (XEXP (lhs, 1)), other = rhs;
else
/* If SRC is masked by an AND that does not make a difference in
the value being stored, strip it. */
if (GET_CODE (assign) == ZERO_EXTRACT
- && GET_CODE (XEXP (assign, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (assign, 1))
&& INTVAL (XEXP (assign, 1)) < HOST_BITS_PER_WIDE_INT
&& GET_CODE (src) == AND
- && GET_CODE (XEXP (src, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (src, 1))
&& ((unsigned HOST_WIDE_INT) INTVAL (XEXP (src, 1))
== ((unsigned HOST_WIDE_INT) 1 << INTVAL (XEXP (assign, 1))) - 1))
src = XEXP (src, 0);
/* If VAROP is a CONST_INT, then we need to apply the mask in CONSTOP
to VAROP and return the new constant. */
- if (GET_CODE (varop) == CONST_INT)
+ if (CONST_INT_P (varop))
return gen_int_mode (INTVAL (varop) & constop, mode);
/* See what bits may be nonzero in VAROP. Unlike the general case of
instead of this kludge. */
if (GET_MODE_BITSIZE (GET_MODE (x)) < GET_MODE_BITSIZE (mode)
- && GET_CODE (tem) == CONST_INT
+ && CONST_INT_P (tem)
&& INTVAL (tem) > 0
&& 0 != (INTVAL (tem)
& ((HOST_WIDE_INT) 1
return 1;
}
\f
+/* A helper to simplify_shift_const_1 to determine the mode we can perform
+ the shift in. The original shift operation CODE is performed on OP in
+ ORIG_MODE. Return the wider mode MODE if we can perform the operation
+ in that mode. Return ORIG_MODE otherwise. We can also assume that the
+ result of the shift is subject to operation OUTER_CODE with operand
+ OUTER_CONST. */
+
+static enum machine_mode
+try_widen_shift_mode (enum rtx_code code, rtx op, int count,
+ enum machine_mode orig_mode, enum machine_mode mode,
+ enum rtx_code outer_code, HOST_WIDE_INT outer_const)
+{
+ if (orig_mode == mode)
+ return mode;
+ gcc_assert (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (orig_mode));
+
+ /* In general we can't perform in wider mode for right shift and rotate. */
+ switch (code)
+ {
+ case ASHIFTRT:
+ /* We can still widen if the bits brought in from the left are identical
+ to the sign bit of ORIG_MODE. */
+ if (num_sign_bit_copies (op, mode)
+ > (unsigned) (GET_MODE_BITSIZE (mode)
+ - GET_MODE_BITSIZE (orig_mode)))
+ return mode;
+ return orig_mode;
+
+ case LSHIFTRT:
+ /* Similarly here but with zero bits. */
+ if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
+ && (nonzero_bits (op, mode) & ~GET_MODE_MASK (orig_mode)) == 0)
+ return mode;
+
+ /* We can also widen if the bits brought in will be masked off. This
+ operation is performed in ORIG_MODE. */
+ if (outer_code == AND)
+ {
+ int care_bits = low_bitmask_len (orig_mode, outer_const);
+
+ if (care_bits >= 0
+ && GET_MODE_BITSIZE (orig_mode) - care_bits >= count)
+ return mode;
+ }
+ /* fall through */
+
+ case ROTATE:
+ return orig_mode;
+
+ case ROTATERT:
+ gcc_unreachable ();
+
+ default:
+ return mode;
+ }
+}
+
/* Simplify a shift of VAROP by COUNT bits. CODE says what kind of shift.
The result of the shift is RESULT_MODE. Return NULL_RTX if we cannot
simplify it. Otherwise, return a simplified value.
count = bitsize - count;
}
- /* We need to determine what mode we will do the shift in. If the
- shift is a right shift or a ROTATE, we must always do it in the mode
- it was originally done in. Otherwise, we can do it in MODE, the
- widest mode encountered. */
- shift_mode
- = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
- ? result_mode : mode);
+ shift_mode = try_widen_shift_mode (code, varop, count, result_mode,
+ mode, outer_op, outer_const);
/* Handle cases where the count is greater than the size of the mode
minus 1. For ASHIFT, use the size minus one as the count (this can
/* Some machines use MULT instead of ASHIFT because MULT
is cheaper. But it is still better on those machines to
merge two shifts into one. */
- if (GET_CODE (XEXP (varop, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (varop, 1))
&& exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
{
varop
case UDIV:
/* Similar, for when divides are cheaper. */
- if (GET_CODE (XEXP (varop, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (varop, 1))
&& exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
{
varop
case ROTATE:
/* Here we have two nested shifts. The result is usually the
AND of a new shift with a mask. We compute the result below. */
- if (GET_CODE (XEXP (varop, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (varop, 1))
&& INTVAL (XEXP (varop, 1)) >= 0
&& INTVAL (XEXP (varop, 1)) < GET_MODE_BITSIZE (GET_MODE (varop))
&& GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
/* Give up if we can't compute an outer operation to use. */
if (mask_rtx == 0
- || GET_CODE (mask_rtx) != CONST_INT
+ || !CONST_INT_P (mask_rtx)
|| ! merge_outer_ops (&outer_op, &outer_const, AND,
INTVAL (mask_rtx),
result_mode, &complement_p))
B is not a constant. */
else if (GET_CODE (varop) == code
- && GET_CODE (XEXP (varop, 0)) == CONST_INT
- && GET_CODE (XEXP (varop, 1)) != CONST_INT)
+ && CONST_INT_P (XEXP (varop, 0))
+ && !CONST_INT_P (XEXP (varop, 1)))
{
rtx new_rtx = simplify_const_binary_operation (code, mode,
XEXP (varop, 0),
what a ZERO_EXTRACT looks like. Also, some machines have
(and (shift)) insns. */
- if (GET_CODE (XEXP (varop, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (varop, 1))
/* We can't do this if we have (ashiftrt (xor)) and the
constant has its sign bit set in shift_mode. */
&& !(code == ASHIFTRT && GET_CODE (varop) == XOR
&& (new_rtx = simplify_const_binary_operation (code, result_mode,
XEXP (varop, 1),
GEN_INT (count))) != 0
- && GET_CODE (new_rtx) == CONST_INT
+ && CONST_INT_P (new_rtx)
&& merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop),
INTVAL (new_rtx), result_mode, &complement_p))
{
logical expression, make a new logical expression, and apply
the inverse distributive law. This also can't be done
for some (ashiftrt (xor)). */
- if (GET_CODE (XEXP (varop, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (varop, 1))
&& !(code == ASHIFTRT && GET_CODE (varop) == XOR
&& 0 > trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
shift_mode)))
/* (ashift (plus foo C) N) is (plus (ashift foo N) C'). */
if (code == ASHIFT
- && GET_CODE (XEXP (varop, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (varop, 1))
&& (new_rtx = simplify_const_binary_operation (ASHIFT, result_mode,
XEXP (varop, 1),
GEN_INT (count))) != 0
- && GET_CODE (new_rtx) == CONST_INT
+ && CONST_INT_P (new_rtx)
&& merge_outer_ops (&outer_op, &outer_const, PLUS,
INTVAL (new_rtx), result_mode, &complement_p))
{
leg for shift(logical). See details in logical handling above
for reasoning in doing so. */
if (code == LSHIFTRT
- && GET_CODE (XEXP (varop, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (varop, 1))
&& mode_signbit_p (result_mode, XEXP (varop, 1))
&& (new_rtx = simplify_const_binary_operation (code, result_mode,
XEXP (varop, 1),
GEN_INT (count))) != 0
- && GET_CODE (new_rtx) == CONST_INT
+ && CONST_INT_P (new_rtx)
&& merge_outer_ops (&outer_op, &outer_const, XOR,
INTVAL (new_rtx), result_mode, &complement_p))
{
&& GET_CODE (XEXP (varop, 0)) == ASHIFTRT
&& count == (GET_MODE_BITSIZE (GET_MODE (varop)) - 1)
&& (code == LSHIFTRT || code == ASHIFTRT)
- && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (varop, 0), 1))
&& INTVAL (XEXP (XEXP (varop, 0), 1)) == count
&& rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
{
if the truncate does not affect the value. */
if (code == LSHIFTRT
&& GET_CODE (XEXP (varop, 0)) == LSHIFTRT
- && GET_CODE (XEXP (XEXP (varop, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (varop, 0), 1))
&& (INTVAL (XEXP (XEXP (varop, 0), 1))
>= (GET_MODE_BITSIZE (GET_MODE (XEXP (varop, 0)))
- GET_MODE_BITSIZE (GET_MODE (varop)))))
break;
}
- /* We need to determine what mode to do the shift in. If the shift is
- a right shift or ROTATE, we must always do it in the mode it was
- originally done in. Otherwise, we can do it in MODE, the widest mode
- encountered. The code we care about is that of the shift that will
- actually be done, not the shift that was originally requested. */
- shift_mode
- = (code == ASHIFTRT || code == LSHIFTRT || code == ROTATE
- ? result_mode : mode);
+ shift_mode = try_widen_shift_mode (code, varop, count, result_mode, mode,
+ outer_op, outer_const);
/* We have now finished analyzing the shift. The result should be
a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places. If
constant integer or has a mode the same size. */
if (GET_MODE_SIZE (omode) > UNITS_PER_WORD
&& ! ((imode == VOIDmode
- && (GET_CODE (x) == CONST_INT
+ && (CONST_INT_P (x)
|| GET_CODE (x) == CONST_DOUBLE))
|| isize == osize))
goto fail;
&& GET_CODE (XEXP (XEXP (op1, 0), 0)) == SUBREG
&& (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0)))
== GET_MODE (SUBREG_REG (XEXP (XEXP (op1, 0), 0))))
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& XEXP (op0, 1) == XEXP (op1, 1)
&& XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
&& XEXP (op0, 1) == XEXP (XEXP (op1, 0), 1)
|| (GET_CODE (op0) == ASHIFTRT
&& (code != GTU && code != LTU
&& code != GEU && code != LEU)))
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& INTVAL (XEXP (op0, 1)) >= 0
&& INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
&& XEXP (op0, 1) == XEXP (op1, 1))
present. */
else if (GET_CODE (op0) == AND && GET_CODE (op1) == AND
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
- && GET_CODE (XEXP (op1, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (op0, 1))
+ && CONST_INT_P (XEXP (op1, 1)))
{
rtx inner_op0 = XEXP (op0, 0);
rtx inner_op1 = XEXP (op1, 0);
but some things may really be comparisons with zero but not start
out looking that way. */
- while (GET_CODE (op1) == CONST_INT)
+ while (CONST_INT_P (op1))
{
enum machine_mode mode = GET_MODE (op0);
unsigned int mode_width = GET_MODE_BITSIZE (mode);
/* Except we can't if SHIFT_COUNT_TRUNCATED is set, since we might
have already reduced the shift count modulo the word size. */
if (!SHIFT_COUNT_TRUNCATED
- && GET_CODE (XEXP (op0, 0)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 0))
&& XEXP (op0, 1) == const1_rtx
&& equality_comparison_p && const_op == 0
&& (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
case ROTATE:
/* If we are testing equality and our count is a constant, we
can perform the inverse operation on our RHS. */
- if (equality_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ if (equality_comparison_p && CONST_INT_P (XEXP (op0, 1))
&& (tem = simplify_binary_operation (ROTATERT, mode,
op1, XEXP (op0, 1))) != 0)
{
a particular bit. Convert it to an AND of a constant of that
bit. This will be converted into a ZERO_EXTRACT. */
if (const_op == 0 && sign_bit_comparison_p
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& mode_width <= HOST_BITS_PER_WIDE_INT)
{
op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
&& subreg_lowpart_p (op0)
&& GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) > mode_width
&& GET_CODE (SUBREG_REG (op0)) == PLUS
- && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (SUBREG_REG (op0), 1)))
{
enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
rtx a = XEXP (SUBREG_REG (op0), 0);
/* The sign bit of (minus (ashiftrt X C) X), where C is the number
of bits in X minus 1, is one iff X > 0. */
if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == ASHIFTRT
- && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
&& (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (op0, 0), 1))
== mode_width - 1
&& rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
in STORE_FLAG_VALUE, we can compare with X. */
if (const_op == 0 && equality_comparison_p
&& mode_width <= HOST_BITS_PER_WIDE_INT
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& GET_CODE (XEXP (op0, 0)) == LSHIFTRT
- && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
&& INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
&& INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT)
{
the underlying value. */
if (equality_comparison_p
&& const_op == 0
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& mode_width <= HOST_BITS_PER_WIDE_INT
&& ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
== (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)))
known to hold a value of the required mode the
transformation is invalid. */
if ((equality_comparison_p || unsigned_comparison_p)
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& (i = exact_log2 ((INTVAL (XEXP (op0, 1))
& GET_MODE_MASK (mode))
+ 1)) >= 0
#endif
|| (mode_width <= GET_MODE_BITSIZE (tmode)
&& subreg_lowpart_p (XEXP (op0, 0))))
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& mode_width <= HOST_BITS_PER_WIDE_INT
&& GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT
&& ((c1 = INTVAL (XEXP (op0, 1))) & ~mask) == 0
if (GET_CODE (shift_op) == NOT
|| (GET_CODE (shift_op) == XOR
- && GET_CODE (XEXP (shift_op, 1)) == CONST_INT
- && GET_CODE (shift_count) == CONST_INT
+ && CONST_INT_P (XEXP (shift_op, 1))
+ && CONST_INT_P (shift_count)
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& (INTVAL (XEXP (shift_op, 1))
== (HOST_WIDE_INT) 1 << INTVAL (shift_count))))
are known to be zero, we can do this by comparing FOO with C
shifted right N bits so long as the low-order N bits of C are
zero. */
- if (GET_CODE (XEXP (op0, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (op0, 1))
&& INTVAL (XEXP (op0, 1)) >= 0
&& ((INTVAL (XEXP (op0, 1)) + ! equality_comparison_p)
< HOST_BITS_PER_WIDE_INT)
/* If we are doing a sign bit comparison, it means we are testing
a particular bit. Convert it to the appropriate AND. */
- if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ if (sign_bit_comparison_p && CONST_INT_P (XEXP (op0, 1))
&& mode_width <= HOST_BITS_PER_WIDE_INT)
{
op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
the low bit to the sign bit, we can convert this to an AND of the
low-order bit. */
if (const_op == 0 && equality_comparison_p
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
== mode_width - 1)
{
/* If this is an equality comparison with zero, we can do this
as a logical shift, which might be much simpler. */
if (equality_comparison_p && const_op == 0
- && GET_CODE (XEXP (op0, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (op0, 1)))
{
op0 = simplify_shift_const (NULL_RTX, LSHIFTRT, mode,
XEXP (op0, 0),
/* If OP0 is a sign extension and CODE is not an unsigned comparison,
do the comparison in a narrower mode. */
if (! unsigned_comparison_p
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& GET_CODE (XEXP (op0, 0)) == ASHIFT
&& XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
&& (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
constant, which is usually represented with the PLUS
between the shifts. */
if (! unsigned_comparison_p
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& GET_CODE (XEXP (op0, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
&& GET_CODE (XEXP (XEXP (op0, 0), 0)) == ASHIFT
&& XEXP (op0, 1) == XEXP (XEXP (XEXP (op0, 0), 0), 1)
&& (tmode = mode_for_size (mode_width - INTVAL (XEXP (op0, 1)),
the low order N bits of FOO are known to be zero, we can do this
by comparing FOO with C shifted left N bits so long as no
overflow occurs. */
- if (GET_CODE (XEXP (op0, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (op0, 1))
&& INTVAL (XEXP (op0, 1)) >= 0
&& INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
&& mode_width <= HOST_BITS_PER_WIDE_INT
can replace this with an LT or GE comparison. */
if (const_op == 0
&& (equality_comparison_p || sign_bit_comparison_p)
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (op0, 1))
&& (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
== mode_width - 1)
{
|| code == LEU || code == LTU)
&& (nonzero_bits (op0, tmode)
& ~GET_MODE_MASK (mode)) == 0
- && ((GET_CODE (op1) == CONST_INT
+ && ((CONST_INT_P (op1)
|| (nonzero_bits (op1, tmode)
& ~GET_MODE_MASK (mode)) == 0)));
XEXP (op0, 1)));
op0 = gen_lowpart (tmode, op0);
- if (zero_extended && GET_CODE (op1) == CONST_INT)
+ if (zero_extended && CONST_INT_P (op1))
op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (mode));
op1 = gen_lowpart (tmode, op1);
break;
return;
if (where_dead
+ && BLOCK_FOR_INSN (where_dead) == BLOCK_FOR_INSN (to_insn)
&& DF_INSN_LUID (where_dead) >= from_luid
&& DF_INSN_LUID (where_dead) < DF_INSN_LUID (to_insn))
{