/* - or it is an address that can't trap plus a constant integer,
with the proper remainder modulo the mode size if we are
considering unaligned memory references. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& !rtx_addr_can_trap_p_1 (XEXP (x, 0), offset + INTVAL (XEXP (x, 1)),
size, mode, unaligned_mems))
return 0;
return nonzero_address_p (XEXP (x, 0));
case PLUS:
- if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ if (CONST_INT_P (XEXP (x, 1)))
return nonzero_address_p (XEXP (x, 0));
/* Handle PIC references. */
else if (XEXP (x, 0) == pic_offset_table_rtx
/* Similar to the above; allow positive offsets. Further, since
auto-inc is only allowed in memories, the register must be a
pointer. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) > 0)
return true;
return nonzero_address_p (XEXP (x, 0));
x = XEXP (x, 0);
if (GET_CODE (x) == MINUS
- && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (x, 1)))
return - INTVAL (XEXP (x, 1));
if (GET_CODE (x) == PLUS
- && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (x, 1)))
return INTVAL (XEXP (x, 1));
return 0;
}
return 0;
x = XEXP (x, 0);
if (GET_CODE (x) == PLUS
- && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (x, 1)))
return XEXP (x, 0);
else if (GET_CODE (x) == MINUS
- && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (x, 1)))
return XEXP (x, 0);
return 0;
}
if (GET_CODE (x) == CONST)
{
x = XEXP (x, 0);
- if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
{
*base_out = XEXP (x, 0);
*offset_out = XEXP (x, 1);
}
\f
-/* Add register note with kind KIND and datum DATUM to INSN. */
+/* Allocate a register note with kind KIND and datum DATUM. LIST is
+ stored as the pointer to the next register note. */
-void
-add_reg_note (rtx insn, enum reg_note kind, rtx datum)
+rtx
+alloc_reg_note (enum reg_note kind, rtx datum, rtx list)
{
rtx note;
/* These types of register notes use an INSN_LIST rather than an
EXPR_LIST, so that copying is done right and dumps look
better. */
- note = alloc_INSN_LIST (datum, REG_NOTES (insn));
+ note = alloc_INSN_LIST (datum, list);
PUT_REG_NOTE_KIND (note, kind);
break;
default:
- note = alloc_EXPR_LIST (kind, datum, REG_NOTES (insn));
+ note = alloc_EXPR_LIST (kind, datum, list);
break;
}
- REG_NOTES (insn) = note;
+ return note;
+}
+
+/* Add register note with kind KIND and datum DATUM to INSN. */
+
+void
+add_reg_note (rtx insn, enum reg_note kind, rtx datum)
+{
+ REG_NOTES (insn) = alloc_reg_note (kind, datum, REG_NOTES (insn));
}
/* Remove register note NOTE from the REG_NOTES of INSN. */
{
rtx new_rtx = replace_rtx (SUBREG_REG (x), from, to);
- if (GET_CODE (new_rtx) == CONST_INT)
+ if (CONST_INT_P (new_rtx))
{
x = simplify_subreg (GET_MODE (x), new_rtx,
GET_MODE (SUBREG_REG (x)),
{
rtx new_rtx = replace_rtx (XEXP (x, 0), from, to);
- if (GET_CODE (new_rtx) == CONST_INT)
+ if (CONST_INT_P (new_rtx))
{
x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
new_rtx, GET_MODE (XEXP (x, 0)));
if (JUMP_P (insn)
&& (label = JUMP_LABEL (insn)) != NULL_RTX
&& (table = next_active_insn (label)) != NULL_RTX
- && JUMP_P (table)
- && (GET_CODE (PATTERN (table)) == ADDR_VEC
- || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
+ && JUMP_TABLE_DATA_P (table))
{
if (labelp)
*labelp = label;
break;
case ZERO_EXTRACT:
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
nonzero &= ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1;
break;
the shift when shifted the appropriate number of bits. This
shows that high-order bits are cleared by the right shift and
low-order bits by left shifts. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) >= 0
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
&& INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (GET_MODE (x)))
break;
case SIGN_EXTRACT:
- if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ if (CONST_INT_P (XEXP (x, 1)))
return MAX (1, (int) bitwidth - INTVAL (XEXP (x, 1)));
break;
/* If we are rotating left by a number of bits less than the number
of sign bit copies, we can just subtract that amount from the
number. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) >= 0
&& INTVAL (XEXP (x, 1)) < (int) bitwidth)
{
if (code == AND
&& num1 > 1
&& bitwidth <= HOST_BITS_PER_WIDE_INT
- && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (x, 1))
&& !(INTVAL (XEXP (x, 1)) & ((HOST_WIDE_INT) 1 << (bitwidth - 1))))
return num1;
if (code == IOR
&& num1 > 1
&& bitwidth <= HOST_BITS_PER_WIDE_INT
- && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (x, 1))
&& (INTVAL (XEXP (x, 1)) & ((HOST_WIDE_INT) 1 << (bitwidth - 1))))
return num1;
sign bit. */
num0 = cached_num_sign_bit_copies (XEXP (x, 0), mode,
known_x, known_mode, known_ret);
- 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 (GET_MODE (x)))
num0 = MIN ((int) bitwidth, num0 + INTVAL (XEXP (x, 1)));
case ASHIFT:
/* Left shifts destroy copies. */
- if (GET_CODE (XEXP (x, 1)) != CONST_INT
+ if (!CONST_INT_P (XEXP (x, 1))
|| INTVAL (XEXP (x, 1)) < 0
|| INTVAL (XEXP (x, 1)) >= (int) bitwidth
|| INTVAL (XEXP (x, 1)) >= GET_MODE_BITSIZE (GET_MODE (x)))
overflow. */
if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_CC
- && GET_CODE (op1) == CONST_INT
+ && CONST_INT_P (op1)
&& GET_MODE (op0) != VOIDmode
&& GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
{
x = avoid_constant_pool_reference (x);
return GET_CODE (x) == CONST_DOUBLE;
}
+\f
+/* If M is a bitmask that selects a field of low-order bits within an item but
+ not the entire word, return the length of the field. Return -1 otherwise.
+ M is used in machine mode MODE. */
+int
+low_bitmask_len (enum machine_mode mode, unsigned HOST_WIDE_INT m)
+{
+ if (mode != VOIDmode)
+ {
+ if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
+ return -1;
+ m &= GET_MODE_MASK (mode);
+ }
+
+ return exact_log2 (m + 1);
+}