((((HOST_WIDE_INT) low) < 0) ? ((HOST_WIDE_INT) -1) : ((HOST_WIDE_INT) 0))
static rtx neg_const_int (enum machine_mode, rtx);
-static bool mode_signbit_p (enum machine_mode, rtx);
static int simplify_plus_minus_op_data_cmp (const void *, const void *);
static rtx simplify_plus_minus (enum rtx_code, enum machine_mode, rtx,
rtx, int);
/* Test whether expression, X, is an immediate constant that represents
the most significant bit of machine mode MODE. */
-static bool
+bool
mode_signbit_p (enum machine_mode mode, rtx x)
{
unsigned HOST_WIDE_INT val;
trueop1 = avoid_constant_pool_reference (op1);
if (VECTOR_MODE_P (mode)
+ && code != VEC_CONCAT
&& GET_CODE (trueop0) == CONST_VECTOR
&& GET_CODE (trueop1) == CONST_VECTOR)
{
!= ((HOST_WIDE_INT) (-1) << (width - 1))))
val &= ((HOST_WIDE_INT) 1 << width) - 1;
- return GEN_INT (val);
+ return gen_int_mode (val, mode);
}
break;
}
/* Recurse for further possible simplifications. */
- newx = simplify_subreg (outermode, SUBREG_REG (op),
- GET_MODE (SUBREG_REG (op)),
- final_offset);
+ newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
+ final_offset);
if (newx)
return newx;
- return gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
+ if (validate_subreg (outermode, innermostmode,
+ SUBREG_REG (op), final_offset))
+ return gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
+ return NULL_RTX;
}
/* SUBREG of a hard register => just change the register number
&& subreg_offset_representable_p (REGNO (op), innermode,
byte, outermode))
{
- rtx tem = gen_rtx_SUBREG (outermode, op, byte);
- int final_regno = subreg_hard_regno (tem, 0);
+ unsigned int regno = REGNO (op);
+ unsigned int final_regno
+ = regno + subreg_regno_offset (regno, innermode, byte, outermode);
/* ??? We do allow it if the current REG is not valid for
its mode. This is a kludge to work around how float/complex
arguments are passed on 32-bit SPARC and should be fixed. */
if (HARD_REGNO_MODE_OK (final_regno, outermode)
- || ! HARD_REGNO_MODE_OK (REGNO (op), innermode))
+ || ! HARD_REGNO_MODE_OK (regno, innermode))
{
rtx x = gen_rtx_REG_offset (op, outermode, final_regno, byte);
res = simplify_subreg (outermode, part, GET_MODE (part), final_offset);
if (res)
return res;
- /* We can at least simplify it by referring directly to the
- relevant part. */
- return gen_rtx_SUBREG (outermode, part, final_offset);
+ if (validate_subreg (outermode, GET_MODE (part), part, final_offset))
+ return gen_rtx_SUBREG (outermode, part, final_offset);
+ return NULL_RTX;
}
/* Optimize SUBREG truncations of zero and sign extended values. */
enum machine_mode innermode, unsigned int byte)
{
rtx newx;
- /* Little bit of sanity checking. */
- gcc_assert (innermode != VOIDmode);
- gcc_assert (outermode != VOIDmode);
- gcc_assert (innermode != BLKmode);
- gcc_assert (outermode != BLKmode);
-
- gcc_assert (GET_MODE (op) == innermode
- || GET_MODE (op) == VOIDmode);
-
- gcc_assert ((byte % GET_MODE_SIZE (outermode)) == 0);
- gcc_assert (byte < GET_MODE_SIZE (innermode));
newx = simplify_subreg (outermode, op, innermode, byte);
if (newx)
if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode)
return NULL_RTX;
- return gen_rtx_SUBREG (outermode, op, byte);
+ if (validate_subreg (outermode, innermode, op, byte))
+ return gen_rtx_SUBREG (outermode, op, byte);
+
+ return NULL_RTX;
}
+
/* Simplify X, an rtx expression.
Return the simplified expression or NULL if no simplifications