| Index: gcc/gcc/rtlanal.c
|
| diff --git a/gcc/gcc/rtlanal.c b/gcc/gcc/rtlanal.c
|
| index e6cec483b82c8aae05d1a98b3af98407b3c1f385..0e3b77bc0c9f1fbf7df79ddc86ffcb9d139ceabb 100644
|
| --- a/gcc/gcc/rtlanal.c
|
| +++ b/gcc/gcc/rtlanal.c
|
| @@ -39,18 +39,6 @@ along with GCC; see the file COPYING3. If not see
|
| #include "df.h"
|
| #include "tree.h"
|
|
|
| -/* Information about a subreg of a hard register. */
|
| -struct subreg_info
|
| -{
|
| - /* Offset of first hard register involved in the subreg. */
|
| - int offset;
|
| - /* Number of hard registers involved in the subreg. */
|
| - int nregs;
|
| - /* Whether this subreg can be represented as a hard reg with the new
|
| - mode. */
|
| - bool representable_p;
|
| -};
|
| -
|
| /* Forward declarations */
|
| static void set_of_1 (rtx, const_rtx, void *);
|
| static bool covers_regno_p (const_rtx, unsigned int);
|
| @@ -58,9 +46,6 @@ static bool covers_regno_no_parallel_p (const_rtx, unsigned int);
|
| static int rtx_referenced_p_1 (rtx *, void *);
|
| static int computed_jump_p_1 (const_rtx);
|
| static void parms_set (rtx, const_rtx, void *);
|
| -static void subreg_get_info (unsigned int, enum machine_mode,
|
| - unsigned int, enum machine_mode,
|
| - struct subreg_info *);
|
|
|
| static unsigned HOST_WIDE_INT cached_nonzero_bits (const_rtx, enum machine_mode,
|
| const_rtx, enum machine_mode,
|
| @@ -308,7 +293,7 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT offset, HOST_WIDE_INT size,
|
| decl = SYMBOL_REF_DECL (x);
|
|
|
| /* Else check that the access is in bounds. TODO: restructure
|
| - expr_size/lhd_expr_size/int_expr_size and just use the latter. */
|
| + expr_size/tree_expr_size/int_expr_size and just use the latter. */
|
| if (!decl)
|
| decl_size = -1;
|
| else if (DECL_P (decl) && DECL_SIZE_UNIT (decl))
|
| @@ -356,7 +341,7 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT offset, HOST_WIDE_INT size,
|
| /* - 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;
|
| @@ -423,7 +408,7 @@ nonzero_address_p (const_rtx x)
|
| 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
|
| @@ -435,7 +420,7 @@ nonzero_address_p (const_rtx x)
|
| /* 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));
|
| @@ -510,10 +495,10 @@ get_integer_term (const_rtx x)
|
| 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;
|
| }
|
| @@ -529,10 +514,10 @@ get_related_value (const_rtx x)
|
| 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;
|
| }
|
| @@ -581,7 +566,7 @@ split_const (rtx x, rtx *base_out, rtx *offset_out)
|
| 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);
|
| @@ -626,7 +611,7 @@ count_occurrences (const_rtx x, const_rtx find, int count_dest)
|
| if (XEXP (x, 1))
|
| count += count_occurrences (XEXP (x, 1), find, count_dest);
|
| return count;
|
| -
|
| +
|
| case MEM:
|
| if (MEM_P (find) && rtx_equal_p (x, find))
|
| return 1;
|
| @@ -756,7 +741,7 @@ reg_used_between_p (const_rtx reg, const_rtx from_insn, const_rtx to_insn)
|
| return 0;
|
|
|
| for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
|
| - if (INSN_P (insn)
|
| + if (NONDEBUG_INSN_P (insn)
|
| && (reg_overlap_mentioned_p (reg, PATTERN (insn))
|
| || (CALL_P (insn) && find_reg_fusage (insn, USE, reg))))
|
| return 1;
|
| @@ -1880,10 +1865,11 @@ find_regno_fusage (const_rtx insn, enum rtx_code code, unsigned int regno)
|
| }
|
|
|
|
|
| -/* 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;
|
|
|
| @@ -1896,16 +1882,24 @@ add_reg_note (rtx insn, enum reg_note kind, rtx datum)
|
| /* 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. */
|
| @@ -2154,6 +2148,7 @@ side_effects_p (const_rtx x)
|
| case SCRATCH:
|
| case ADDR_VEC:
|
| case ADDR_DIFF_VEC:
|
| + case VAR_LOCATION:
|
| return 0;
|
|
|
| case CLOBBER:
|
| @@ -2257,6 +2252,11 @@ may_trap_p_1 (const_rtx x, unsigned flags)
|
|
|
| /* Memory ref can trap unless it's a static var or a stack slot. */
|
| case MEM:
|
| + /* Recognize specific pattern of stack checking probes. */
|
| + if (flag_stack_check
|
| + && MEM_VOLATILE_P (x)
|
| + && XEXP (x, 0) == stack_pointer_rtx)
|
| + return 1;
|
| if (/* MEM_NOTRAP_P only relates to the actual position of the memory
|
| reference; moving it out of context such as when moving code
|
| when optimizing, might cause its address to become invalid. */
|
| @@ -2501,7 +2501,7 @@ replace_rtx (rtx x, rtx from, rtx to)
|
| {
|
| 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)),
|
| @@ -2517,7 +2517,7 @@ replace_rtx (rtx x, rtx from, rtx to)
|
| {
|
| 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)));
|
| @@ -2647,9 +2647,7 @@ tablejump_p (const_rtx insn, rtx *labelp, rtx *tablep)
|
| 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;
|
| @@ -2780,11 +2778,11 @@ for_each_rtx_1 (rtx exp, int n, rtx_function f, void *data)
|
| else if (result != 0)
|
| /* Stop the traversal. */
|
| return result;
|
| -
|
| +
|
| if (*x == NULL_RTX)
|
| /* There are no sub-expressions. */
|
| continue;
|
| -
|
| +
|
| i = non_rtx_starting_operands[GET_CODE (*x)];
|
| if (i >= 0)
|
| {
|
| @@ -2809,11 +2807,11 @@ for_each_rtx_1 (rtx exp, int n, rtx_function f, void *data)
|
| else if (result != 0)
|
| /* Stop the traversal. */
|
| return result;
|
| -
|
| +
|
| if (*x == NULL_RTX)
|
| /* There are no sub-expressions. */
|
| continue;
|
| -
|
| +
|
| i = non_rtx_starting_operands[GET_CODE (*x)];
|
| if (i >= 0)
|
| {
|
| @@ -2913,7 +2911,7 @@ int
|
| commutative_operand_precedence (rtx op)
|
| {
|
| enum rtx_code code = GET_CODE (op);
|
| -
|
| +
|
| /* Constants always come the second operand. Prefer "nice" constants. */
|
| if (code == CONST_INT)
|
| return -8;
|
| @@ -2960,7 +2958,7 @@ commutative_operand_precedence (rtx op)
|
| operand. In particular, (plus (minus (reg) (reg)) (neg (reg)))
|
| is canonical, although it will usually be further simplified. */
|
| return 2;
|
| -
|
| +
|
| case RTX_UNARY:
|
| /* Then prefer NEG and NOT. */
|
| if (code == NEG || code == NOT)
|
| @@ -3090,7 +3088,7 @@ subreg_lsb (const_rtx x)
|
| offset - The byte offset.
|
| ymode - The mode of a top level SUBREG (or what may become one).
|
| info - Pointer to structure to fill in. */
|
| -static void
|
| +void
|
| subreg_get_info (unsigned int xregno, enum machine_mode xmode,
|
| unsigned int offset, enum machine_mode ymode,
|
| struct subreg_info *info)
|
| @@ -3129,10 +3127,10 @@ subreg_get_info (unsigned int xregno, enum machine_mode xmode,
|
| picking a different register class, or doing it in memory if
|
| necessary.) An example of a value with holes is XCmode on 32-bit
|
| x86 with -m128bit-long-double; it's represented in 6 32-bit registers,
|
| - 3 for each part, but in memory it's two 128-bit parts.
|
| + 3 for each part, but in memory it's two 128-bit parts.
|
| Padding is assumed to be at the end (not necessarily the 'high part')
|
| of each unit. */
|
| - if ((offset / GET_MODE_SIZE (xmode_unit) + 1
|
| + if ((offset / GET_MODE_SIZE (xmode_unit) + 1
|
| < GET_MODE_NUNITS (xmode))
|
| && (offset / GET_MODE_SIZE (xmode_unit)
|
| != ((offset + GET_MODE_SIZE (ymode) - 1)
|
| @@ -3144,7 +3142,7 @@ subreg_get_info (unsigned int xregno, enum machine_mode xmode,
|
| }
|
| else
|
| nregs_xmode = hard_regno_nregs[xregno][xmode];
|
| -
|
| +
|
| nregs_ymode = hard_regno_nregs[xregno][ymode];
|
|
|
| /* Paradoxical subregs are otherwise valid. */
|
| @@ -3530,7 +3528,7 @@ label_is_jump_target_p (const_rtx label, const_rtx jump_insn)
|
| /* Return an estimate of the cost of computing rtx X.
|
| One use is in cse, to decide which expression to keep in the hash table.
|
| Another is in rtl generation, to pick the cheapest way to multiply.
|
| - Other uses like the latter are expected in the future.
|
| + Other uses like the latter are expected in the future.
|
|
|
| SPEED parameter specify whether costs optimized for speed or size should
|
| be returned. */
|
| @@ -3604,19 +3602,19 @@ rtx_cost (rtx x, enum rtx_code outer_code ATTRIBUTE_UNUSED, bool speed)
|
| }
|
|
|
| /* Return cost of address expression X.
|
| - Expect that X is properly formed address reference.
|
| + Expect that X is properly formed address reference.
|
|
|
| SPEED parameter specify whether costs optimized for speed or size should
|
| be returned. */
|
|
|
| int
|
| -address_cost (rtx x, enum machine_mode mode, bool speed)
|
| +address_cost (rtx x, enum machine_mode mode, addr_space_t as, bool speed)
|
| {
|
| /* We may be asked for cost of various unusual addresses, such as operands
|
| of push instruction. It is not worthwhile to complicate writing
|
| of the target hook by such cases. */
|
|
|
| - if (!memory_address_p (mode, x))
|
| + if (!memory_address_addr_space_p (mode, x, as))
|
| return 1000;
|
|
|
| return targetm.address_cost (x, speed);
|
| @@ -3755,7 +3753,11 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
|
| /* If pointers extend unsigned and this is a pointer in Pmode, say that
|
| all the bits above ptr_mode are known to be zero. */
|
| - if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
|
| + /* As we do not know which address space the pointer is refering to,
|
| + we can do this only if the target does not support different pointer
|
| + or address modes depending on the address space. */
|
| + if (target_default_pointer_address_modes_p ()
|
| + && POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
|
| && REG_POINTER (x))
|
| nonzero &= GET_MODE_MASK (ptr_mode);
|
| #endif
|
| @@ -3827,8 +3829,8 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| /* If this produces an integer result, we know which bits are set.
|
| Code here used to clear bits outside the mode of X, but that is
|
| now done above. */
|
| - /* Mind that MODE is the mode the caller wants to look at this
|
| - operation in, and not the actual operation mode. We can wind
|
| + /* Mind that MODE is the mode the caller wants to look at this
|
| + operation in, and not the actual operation mode. We can wind
|
| up with (subreg:DI (gt:V4HI x y)), and we don't have anything
|
| that describes the results of a vector compare. */
|
| if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
|
| @@ -3992,7 +3994,11 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| /* If pointers extend unsigned and this is an addition or subtraction
|
| to a pointer in Pmode, all the bits above ptr_mode are known to be
|
| zero. */
|
| - if (POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
|
| + /* As we do not know which address space the pointer is refering to,
|
| + we can do this only if the target does not support different pointer
|
| + or address modes depending on the address space. */
|
| + if (target_default_pointer_address_modes_p ()
|
| + && POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
|
| && (code == PLUS || code == MINUS)
|
| && REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0)))
|
| nonzero &= GET_MODE_MASK (ptr_mode);
|
| @@ -4001,7 +4007,7 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| 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;
|
| @@ -4059,7 +4065,7 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| 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)))
|
| @@ -4266,8 +4272,12 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
|
| /* If pointers extend signed and this is a pointer in Pmode, say that
|
| all the bits above ptr_mode are known to be sign bit copies. */
|
| - if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode
|
| - && REG_POINTER (x))
|
| + /* As we do not know which address space the pointer is refering to,
|
| + we can do this only if the target does not support different pointer
|
| + or address modes depending on the address space. */
|
| + if (target_default_pointer_address_modes_p ()
|
| + && ! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
|
| + && mode == Pmode && REG_POINTER (x))
|
| return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
|
| #endif
|
|
|
| @@ -4354,7 +4364,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_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;
|
|
|
| @@ -4378,7 +4388,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| /* 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)
|
| {
|
| @@ -4424,7 +4434,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| 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;
|
|
|
| @@ -4432,7 +4442,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| 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;
|
|
|
| @@ -4463,7 +4473,11 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| /* If pointers extend signed and this is an addition or subtraction
|
| to a pointer in Pmode, all the bits above ptr_mode are known to be
|
| sign bit copies. */
|
| - if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
|
| + /* As we do not know which address space the pointer is refering to,
|
| + we can do this only if the target does not support different pointer
|
| + or address modes depending on the address space. */
|
| + if (target_default_pointer_address_modes_p ()
|
| + && ! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
|
| && (code == PLUS || code == MINUS)
|
| && REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0)))
|
| result = MAX ((int) (GET_MODE_BITSIZE (Pmode)
|
| @@ -4550,7 +4564,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
| 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)));
|
| @@ -4559,7 +4573,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
|
|
|
| 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)))
|
| @@ -4664,7 +4678,7 @@ insn_rtx_cost (rtx pat, bool speed)
|
|
|
| If WANT_REG is nonzero, we wish the condition to be relative to that
|
| register, if possible. Therefore, do not canonicalize the condition
|
| - further. If ALLOW_CC_MODE is nonzero, allow the condition returned
|
| + further. If ALLOW_CC_MODE is nonzero, allow the condition returned
|
| to be a compare to a CC mode register.
|
|
|
| If VALID_AT_INSN_P, the condition must be valid at both *EARLIEST
|
| @@ -4741,7 +4755,11 @@ canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest,
|
| stop if it isn't a single set or if it has a REG_INC note because
|
| we don't want to bother dealing with it. */
|
|
|
| - if ((prev = prev_nonnote_insn (prev)) == 0
|
| + do
|
| + prev = prev_nonnote_insn (prev);
|
| + while (prev && DEBUG_INSN_P (prev));
|
| +
|
| + if (prev == 0
|
| || !NONJUMP_INSN_P (prev)
|
| || FIND_REG_INC_NOTE (prev, NULL_RTX)
|
| /* In cfglayout mode, there do not have to be labels at the
|
| @@ -4871,7 +4889,7 @@ canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest,
|
| 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)
|
| {
|
| @@ -5048,4 +5066,20 @@ constant_pool_constant_p (rtx x)
|
| x = avoid_constant_pool_reference (x);
|
| return GET_CODE (x) == CONST_DOUBLE;
|
| }
|
| +
|
| +/* 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);
|
| +}
|
|
|