- /* If we weren't given a mode, use the mode of X. If the mode is still
- VOIDmode, we don't know anything. Likewise if one of the modes is
- floating-point. */
-
- if (mode == VOIDmode)
- mode = GET_MODE (x);
-
- if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x)))
- return 1;
-
- bitwidth = GET_MODE_BITSIZE (mode);
-
- /* For a smaller object, just ignore the high bits. */
- if (bitwidth < GET_MODE_BITSIZE (GET_MODE (x)))
- {
- num0 = num_sign_bit_copies_with_known (x, GET_MODE (x));
- return MAX (1,
- num0 - (int) (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth));
- }
-
- if (GET_MODE (x) != VOIDmode && bitwidth > GET_MODE_BITSIZE (GET_MODE (x)))
- {
-#ifndef WORD_REGISTER_OPERATIONS
- /* If this machine does not do all register operations on the entire
- register and MODE is wider than the mode of X, we can say nothing
- at all about the high-order bits. */
- return 1;
-#else
- /* Likewise on machines that do, if the mode of the object is smaller
- than a word and loads of that size don't sign extend, we can say
- nothing about the high order bits. */
- if (GET_MODE_BITSIZE (GET_MODE (x)) < BITS_PER_WORD
-#ifdef LOAD_EXTEND_OP
- && LOAD_EXTEND_OP (GET_MODE (x)) != SIGN_EXTEND
-#endif
- )
- return 1;
-#endif
- }
-
- switch (code)
- {
- case REG:
-
-#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))
- return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
-#endif
-
- if (reg_last_set_value[REGNO (x)] != 0
- && reg_last_set_mode[REGNO (x)] == mode
- && (reg_last_set_label[REGNO (x)] == label_tick
- || (REGNO (x) >= FIRST_PSEUDO_REGISTER
- && REG_N_SETS (REGNO (x)) == 1
- && ! REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start,
- REGNO (x))))
- && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
- return reg_last_set_sign_bit_copies[REGNO (x)];
-
- tem = get_last_value (x);
- if (tem != 0)
- return num_sign_bit_copies_with_known (tem, mode);
-
- if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0
- && GET_MODE_BITSIZE (GET_MODE (x)) == bitwidth)
- return reg_sign_bit_copies[REGNO (x)];
- break;
-
- case MEM:
-#ifdef LOAD_EXTEND_OP
- /* Some RISC machines sign-extend all loads of smaller than a word. */
- if (LOAD_EXTEND_OP (GET_MODE (x)) == SIGN_EXTEND)
- return MAX (1, ((int) bitwidth
- - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1));
-#endif
- break;
-
- case CONST_INT:
- /* If the constant is negative, take its 1's complement and remask.
- Then see how many zero bits we have. */
- nonzero = INTVAL (x) & GET_MODE_MASK (mode);
- if (bitwidth <= HOST_BITS_PER_WIDE_INT
- && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
- nonzero = (~nonzero) & GET_MODE_MASK (mode);
-
- return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1);
-
- case SUBREG:
- /* If this is a SUBREG for a promoted object that is sign-extended
- and we are looking at it in a wider mode, we know that at least the
- high-order bits are known to be sign bit copies. */
-
- if (SUBREG_PROMOTED_VAR_P (x) && ! SUBREG_PROMOTED_UNSIGNED_P (x))
- {
- num0 = num_sign_bit_copies_with_known (SUBREG_REG (x), mode);
- return MAX ((int) bitwidth
- - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1,
- num0);
- }
-
- /* For a smaller object, just ignore the high bits. */
- if (bitwidth <= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))))
- {
- num0 = num_sign_bit_copies_with_known (SUBREG_REG (x), VOIDmode);
- return MAX (1, (num0
- - (int) (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
- - bitwidth)));
- }
-
-#ifdef WORD_REGISTER_OPERATIONS
-#ifdef LOAD_EXTEND_OP
- /* For paradoxical SUBREGs on machines where all register operations
- affect the entire register, just look inside. Note that we are
- passing MODE to the recursive call, so the number of sign bit copies
- will remain relative to that mode, not the inner mode. */
-
- /* This works only if loads sign extend. Otherwise, if we get a
- reload for the inner part, it may be loaded from the stack, and
- then we lose all sign bit copies that existed before the store
- to the stack. */
-
- if ((GET_MODE_SIZE (GET_MODE (x))
- > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
- && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND
- && GET_CODE (SUBREG_REG (x)) == MEM)
- return num_sign_bit_copies_with_known (SUBREG_REG (x), mode);
-#endif
-#endif
- break;
-
- case SIGN_EXTRACT:
- if (GET_CODE (XEXP (x, 1)) == CONST_INT)
- return MAX (1, (int) bitwidth - INTVAL (XEXP (x, 1)));
- break;
-
- case SIGN_EXTEND:
- return (bitwidth - GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
- + num_sign_bit_copies_with_known (XEXP (x, 0), VOIDmode));
-
- case TRUNCATE:
- /* For a smaller object, just ignore the high bits. */
- num0 = num_sign_bit_copies_with_known (XEXP (x, 0), VOIDmode);
- return MAX (1, (num0 - (int) (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
- - bitwidth)));
-
- case NOT:
- return num_sign_bit_copies_with_known (XEXP (x, 0), mode);
-
- case ROTATE: case ROTATERT:
- /* 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
- && INTVAL (XEXP (x, 1)) >= 0
- && INTVAL (XEXP (x, 1)) < (int) bitwidth)
- {
- num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
- return MAX (1, num0 - (code == ROTATE ? INTVAL (XEXP (x, 1))
- : (int) bitwidth - INTVAL (XEXP (x, 1))));
- }
- break;
-
- case NEG:
- /* In general, this subtracts one sign bit copy. But if the value
- is known to be positive, the number of sign bit copies is the
- same as that of the input. Finally, if the input has just one bit
- that might be nonzero, all the bits are copies of the sign bit. */
- num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
- if (bitwidth > HOST_BITS_PER_WIDE_INT)
- return num0 > 1 ? num0 - 1 : 1;
-
- nonzero = nonzero_bits (XEXP (x, 0), mode);
- if (nonzero == 1)
- return bitwidth;
-
- if (num0 > 1
- && (((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero))
- num0--;
-
- return num0;
-
- case IOR: case AND: case XOR:
- case SMIN: case SMAX: case UMIN: case UMAX:
- /* Logical operations will preserve the number of sign-bit copies.
- MIN and MAX operations always return one of the operands. */
- num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
- num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
- return MIN (num0, num1);
-
- case PLUS: case MINUS:
- /* For addition and subtraction, we can have a 1-bit carry. However,
- if we are subtracting 1 from a positive number, there will not
- be such a carry. Furthermore, if the positive number is known to
- be 0 or 1, we know the result is either -1 or 0. */
-
- if (code == PLUS && XEXP (x, 1) == constm1_rtx
- && bitwidth <= HOST_BITS_PER_WIDE_INT)
- {
- nonzero = nonzero_bits (XEXP (x, 0), mode);
- if ((((HOST_WIDE_INT) 1 << (bitwidth - 1)) & nonzero) == 0)
- return (nonzero == 1 || nonzero == 0 ? bitwidth
- : bitwidth - floor_log2 (nonzero) - 1);
- }
-
- num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
- num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
- result = MAX (1, MIN (num0, num1) - 1);
-
-#ifdef POINTERS_EXTEND_UNSIGNED
- /* 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
- && (code == PLUS || code == MINUS)
- && GET_CODE (XEXP (x, 0)) == REG && REG_POINTER (XEXP (x, 0)))
- result = MAX ((int) (GET_MODE_BITSIZE (Pmode)
- - GET_MODE_BITSIZE (ptr_mode) + 1),
- result);
-#endif
- return result;
-
- case MULT:
- /* The number of bits of the product is the sum of the number of
- bits of both terms. However, unless one of the terms if known
- to be positive, we must allow for an additional bit since negating
- a negative number can remove one sign bit copy. */
-
- num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
- num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
-
- result = bitwidth - (bitwidth - num0) - (bitwidth - num1);
- if (result > 0
- && (bitwidth > HOST_BITS_PER_WIDE_INT
- || (((nonzero_bits (XEXP (x, 0), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
- && ((nonzero_bits (XEXP (x, 1), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))))
- result--;
-
- return MAX (1, result);
-
- case UDIV:
- /* The result must be <= the first operand. If the first operand
- has the high bit set, we know nothing about the number of sign
- bit copies. */
- if (bitwidth > HOST_BITS_PER_WIDE_INT)
- return 1;
- else if ((nonzero_bits (XEXP (x, 0), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
- return 1;
- else
- return num_sign_bit_copies_with_known (XEXP (x, 0), mode);
-
- case UMOD:
- /* The result must be <= the second operand. */
- return num_sign_bit_copies_with_known (XEXP (x, 1), mode);
-
- case DIV:
- /* Similar to unsigned division, except that we have to worry about
- the case where the divisor is negative, in which case we have
- to add 1. */
- result = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
- if (result > 1
- && (bitwidth > HOST_BITS_PER_WIDE_INT
- || (nonzero_bits (XEXP (x, 1), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
- result--;
-
- return result;
-
- case MOD:
- result = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
- if (result > 1
- && (bitwidth > HOST_BITS_PER_WIDE_INT
- || (nonzero_bits (XEXP (x, 1), mode)
- & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0))
- result--;
-
- return result;
-
- case ASHIFTRT:
- /* Shifts by a constant add to the number of bits equal to the
- sign bit. */
- num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
- && INTVAL (XEXP (x, 1)) > 0)
- num0 = MIN ((int) bitwidth, num0 + INTVAL (XEXP (x, 1)));
-
- return num0;
-
- case ASHIFT:
- /* Left shifts destroy copies. */
- if (GET_CODE (XEXP (x, 1)) != CONST_INT
- || INTVAL (XEXP (x, 1)) < 0
- || INTVAL (XEXP (x, 1)) >= (int) bitwidth)
- return 1;
-
- num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
- return MAX (1, num0 - INTVAL (XEXP (x, 1)));
-
- case IF_THEN_ELSE:
- num0 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
- num1 = num_sign_bit_copies_with_known (XEXP (x, 2), mode);
- return MIN (num0, num1);
-
- case EQ: case NE: case GE: case GT: case LE: case LT:
- case UNEQ: case LTGT: case UNGE: case UNGT: case UNLE: case UNLT:
- case GEU: case GTU: case LEU: case LTU:
- case UNORDERED: case ORDERED:
- /* If the constant is negative, take its 1's complement and remask.
- Then see how many zero bits we have. */
- nonzero = STORE_FLAG_VALUE;
- if (bitwidth <= HOST_BITS_PER_WIDE_INT
- && (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
- nonzero = (~nonzero) & GET_MODE_MASK (mode);
-
- return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1);
- break;
-
- default:
- break;
- }
-
- /* If we haven't been able to figure it out by one of the above rules,
- see if some of the high-order bits are known to be zero. If so,
- count those bits and return one less than that amount. If we can't
- safely compute the mask for this mode, always return BITWIDTH. */
-
- if (bitwidth > HOST_BITS_PER_WIDE_INT)
- return 1;
-
- nonzero = nonzero_bits (x, mode);
- return (nonzero & ((HOST_WIDE_INT) 1 << (bitwidth - 1))
- ? 1 : bitwidth - floor_log2 (nonzero) - 1);