from1 = adjust_address (data->from, mode, data->offset);
if (HAVE_PRE_DECREMENT && data->explicit_inc_to < 0)
- emit_insn (gen_add2_insn (data->to_addr, GEN_INT (-size)));
+ emit_insn (gen_add2_insn (data->to_addr,
+ GEN_INT (-(HOST_WIDE_INT)size)));
if (HAVE_PRE_DECREMENT && data->explicit_inc_from < 0)
- emit_insn (gen_add2_insn (data->from_addr, GEN_INT (-size)));
+ emit_insn (gen_add2_insn (data->from_addr,
+ GEN_INT (-(HOST_WIDE_INT)size)));
if (data->to)
emit_insn ((*genfun) (to1, from1));
enum machine_mode mode = GET_MODE (x);
enum machine_mode submode;
enum mode_class class = GET_MODE_CLASS (mode);
- unsigned int i;
if ((unsigned int) mode >= (unsigned int) MAX_MACHINE_MODE)
abort ();
/* In case we output to the stack, but the size is smaller machine can
push exactly, we need to use move instructions. */
if (stack
- && PUSH_ROUNDING (GET_MODE_SIZE (submode)) != GET_MODE_SIZE (submode))
+ && (PUSH_ROUNDING (GET_MODE_SIZE (submode))
+ != GET_MODE_SIZE (submode)))
{
rtx temp;
- int offset1, offset2;
+ HOST_WIDE_INT offset1, offset2;
/* Do not use anti_adjust_stack, since we don't want to update
stack_pointer_delta. */
#endif
stack_pointer_rtx,
GEN_INT
- (PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x)))),
- stack_pointer_rtx,
- 0,
- OPTAB_LIB_WIDEN);
+ (PUSH_ROUNDING
+ (GET_MODE_SIZE (GET_MODE (x)))),
+ stack_pointer_rtx, 0, OPTAB_LIB_WIDEN);
+
if (temp != stack_pointer_rtx)
emit_move_insn (stack_pointer_rtx, temp);
+
#ifdef STACK_GROWS_DOWNWARD
offset1 = 0;
offset2 = GET_MODE_SIZE (submode);
offset2 = (-PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x)))
+ GET_MODE_SIZE (submode));
#endif
+
emit_move_insn (change_address (x, submode,
gen_rtx_PLUS (Pmode,
stack_pointer_rtx,
if (GET_MODE_BITSIZE (mode) < 2 * BITS_PER_WORD
&& (reload_in_progress | reload_completed) == 0)
{
- int packed_dest_p = (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER);
- int packed_src_p = (REG_P (y) && REGNO (y) < FIRST_PSEUDO_REGISTER);
+ int packed_dest_p
+ = (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER);
+ int packed_src_p
+ = (REG_P (y) && REGNO (y) < FIRST_PSEUDO_REGISTER);
if (packed_dest_p || packed_src_p)
{
if (packed_dest_p)
{
rtx sreg = gen_rtx_SUBREG (reg_mode, x, 0);
+
emit_move_insn_1 (cmem, y);
return emit_move_insn_1 (sreg, mem);
}
else
{
rtx sreg = gen_rtx_SUBREG (reg_mode, y, 0);
+
emit_move_insn_1 (mem, sreg);
return emit_move_insn_1 (x, cmem);
}
&& ! (reload_in_progress || reload_completed)
&& (GET_CODE (realpart_x) == SUBREG
|| GET_CODE (imagpart_x) == SUBREG))
- {
- emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
- }
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
(realpart_x, realpart_y));
rtx last_insn = 0;
rtx seq, inner;
int need_clobber;
+ int i;
#ifdef PUSH_ROUNDING
#endif
stack_pointer_rtx,
GEN_INT
- (PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x)))),
- stack_pointer_rtx,
- 0,
- OPTAB_LIB_WIDEN);
+ (PUSH_ROUNDING
+ (GET_MODE_SIZE (GET_MODE (x)))),
+ stack_pointer_rtx, 0, OPTAB_LIB_WIDEN);
+
if (temp != stack_pointer_rtx)
emit_move_insn (stack_pointer_rtx, temp);
code = GET_CODE (XEXP (x, 0));
+
/* Just hope that small offsets off SP are OK. */
if (code == POST_INC)
temp = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- GEN_INT (-(HOST_WIDE_INT)
- GET_MODE_SIZE (GET_MODE (x))));
+ GEN_INT (-((HOST_WIDE_INT)
+ GET_MODE_SIZE (GET_MODE (x)))));
else if (code == POST_DEC)
temp = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
GEN_INT (GET_MODE_SIZE (GET_MODE (x))));
if (x != y
&& ! (reload_in_progress || reload_completed)
&& need_clobber != 0)
- {
- emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
- }
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
emit_insn (seq);
if (offset != 0)
{
- rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
+ rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
if (GET_CODE (to_rtx) != MEM)
abort ();
&& (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
&& MEM_ALIGN (to_rtx) == GET_MODE_ALIGNMENT (mode1))
{
- rtx temp
- = adjust_address (to_rtx, mode1, bitpos / BITS_PER_UNIT);
-
- if (GET_CODE (XEXP (temp, 0)) == REG)
- to_rtx = temp;
- else
- to_rtx = (replace_equiv_address
- (to_rtx, force_reg (GET_MODE (XEXP (temp, 0)),
- XEXP (temp, 0))));
+ to_rtx = adjust_address (to_rtx, mode1, bitpos / BITS_PER_UNIT);
bitpos = 0;
}
and then convert to the wider mode. Our value is the computed
expression. */
{
+ rtx inner_target = 0;
+
/* If we don't want a value, we can do the conversion inside EXP,
which will often result in some optimizations. Do the conversion
in two steps: first change the signedness, if needed, then
exp = convert (type_for_mode (GET_MODE (SUBREG_REG (target)),
SUBREG_PROMOTED_UNSIGNED_P (target)),
exp);
+
+ inner_target = SUBREG_REG (target);
}
- temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
+ temp = expand_expr (exp, inner_target, VOIDmode, 0);
/* If TEMP is a volatile MEM and we want a result value, make
the access now so it gets done only once. Likewise if
{
temp = gen_lowpart_SUBREG (GET_MODE (target), temp);
SUBREG_PROMOTED_VAR_P (temp) = 1;
- SUBREG_PROMOTED_UNSIGNED_P (temp)
- = SUBREG_PROMOTED_UNSIGNED_P (target);
+ SUBREG_PROMOTED_UNSIGNED_SET (temp,
+ SUBREG_PROMOTED_UNSIGNED_P (target));
}
else
temp = convert_modes (GET_MODE (target),
case REAL_CST:
return REAL_VALUES_IDENTICAL (TREE_REAL_CST (exp), dconst0);
+ case VECTOR_CST:
+ for (elt = TREE_VECTOR_CST_ELTS (exp); elt;
+ elt = TREE_CHAIN (elt))
+ if (!is_zeros_p (TREE_VALUE (elt)))
+ return 0;
+
+ return 1;
+
case CONSTRUCTOR:
if (TREE_TYPE (exp) && TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
return CONSTRUCTOR_ELTS (exp) == NULL_TREE;
get_alias_set (TREE_TYPE (field)));
}
}
- else if (TREE_CODE (type) == ARRAY_TYPE)
+ else if (TREE_CODE (type) == ARRAY_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)
{
tree elt;
int i;
int need_to_clear;
tree domain = TYPE_DOMAIN (type);
tree elttype = TREE_TYPE (type);
- int const_bounds_p = (TYPE_MIN_VALUE (domain)
- && TYPE_MAX_VALUE (domain)
- && host_integerp (TYPE_MIN_VALUE (domain), 0)
- && host_integerp (TYPE_MAX_VALUE (domain), 0));
+ int const_bounds_p;
HOST_WIDE_INT minelt = 0;
HOST_WIDE_INT maxelt = 0;
+ /* Vectors are like arrays, but the domain is stored via an array
+ type indirectly. */
+ if (TREE_CODE (type) == VECTOR_TYPE)
+ {
+ /* Note that although TYPE_DEBUG_REPRESENTATION_TYPE uses
+ the same field as TYPE_DOMAIN, we are not guaranteed that
+ it always will. */
+ domain = TYPE_DEBUG_REPRESENTATION_TYPE (type);
+ domain = TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (domain)));
+ }
+
+ const_bounds_p = (TYPE_MIN_VALUE (domain)
+ && TYPE_MAX_VALUE (domain)
+ && host_integerp (TYPE_MIN_VALUE (domain), 0)
+ && host_integerp (TYPE_MAX_VALUE (domain), 0));
+
/* If we have constant bounds for the range of the type, get them. */
if (const_bounds_p)
{
if (need_to_clear && size > 0)
{
if (! cleared)
- clear_storage (target, GEN_INT (size));
+ {
+ if (REG_P (target))
+ emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
+ else
+ clear_storage (target, GEN_INT (size));
+ }
cleared = 1;
}
else if (REG_P (target))
if (GET_CODE (target) == MEM
&& !MEM_KEEP_ALIAS_SET_P (target)
+ && TREE_CODE (type) == ARRAY_TYPE
&& TYPE_NONALIASED_COMPONENT (type))
{
target = copy_rtx (target);
bitpos = (i * tree_low_cst (TYPE_SIZE (elttype), 1));
if (GET_CODE (target) == MEM && !MEM_KEEP_ALIAS_SET_P (target)
+ && TREE_CODE (type) == ARRAY_TYPE
&& TYPE_NONALIASED_COMPONENT (type))
{
target = copy_rtx (target);
tree count;
enum machine_mode tmode;
- if (unsignedp)
- return expand_and (temp,
- GEN_INT
- (trunc_int_for_mode
- (width_mask,
- GET_MODE (temp) == VOIDmode
- ? value_mode
- : GET_MODE (temp))), NULL_RTX);
-
tmode = GET_MODE (temp);
if (tmode == VOIDmode)
tmode = value_mode;
+
+ if (unsignedp)
+ return expand_and (tmode, temp,
+ GEN_INT (trunc_int_for_mode (width_mask,
+ tmode)),
+ NULL_RTX);
+
count = build_int_2 (GET_MODE_BITSIZE (tmode) - bitsize, 0);
temp = expand_shift (LSHIFT_EXPR, tmode, temp, count, 0, 0);
return expand_shift (RSHIFT_EXPR, tmode, temp, count, 0, 0);
rtx subtarget = get_subtarget (target);
/* Check for a PIC address load. */
- if (flag_pic
- && (GET_CODE (value) == PLUS || GET_CODE (value) == MINUS)
+ if ((GET_CODE (value) == PLUS || GET_CODE (value) == MINUS)
&& XEXP (value, 0) == pic_offset_table_rtx
&& (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
|| GET_CODE (XEXP (value, 1)) == LABEL_REF
are memory and they conflict. */
return ! (rtx_equal_p (x, exp_rtl)
|| (GET_CODE (x) == MEM && GET_CODE (exp_rtl) == MEM
- && true_dependence (exp_rtl, GET_MODE (x), x,
+ && true_dependence (exp_rtl, VOIDmode, x,
rtx_addr_varies_p)));
}
temp = gen_lowpart_SUBREG (mode, DECL_RTL (exp));
SUBREG_PROMOTED_VAR_P (temp) = 1;
- SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
+ SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
return temp;
}
{
temp = gen_lowpart_SUBREG (mode, SAVE_EXPR_RTL (exp));
SUBREG_PROMOTED_VAR_P (temp) = 1;
- SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
+ SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
}
if (temp == const0_rtx)
promote_mode (type, mode, &unsignedp, 0);
temp = gen_lowpart_SUBREG (mode, SAVE_EXPR_RTL (exp));
SUBREG_PROMOTED_VAR_P (temp) = 1;
- SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
+ SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp);
return temp;
}
{
HOST_WIDE_INT bitsize
= TREE_INT_CST_LOW (DECL_SIZE (TREE_PURPOSE (elt)));
+ enum machine_mode imode
+ = TYPE_MODE (TREE_TYPE (TREE_PURPOSE (elt)));
if (TREE_UNSIGNED (TREE_TYPE (TREE_PURPOSE (elt))))
{
op1 = GEN_INT (((HOST_WIDE_INT) 1 << bitsize) - 1);
- op0 = expand_and (op0, op1, target);
+ op0 = expand_and (imode, op0, op1, target);
}
else
{
- enum machine_mode imode
- = TYPE_MODE (TREE_TYPE (TREE_PURPOSE (elt)));
tree count
= build_int_2 (GET_MODE_BITSIZE (imode) - bitsize,
0);
if (offset != 0)
{
- rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
+ rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
/* If this object is in a register, put it into memory.
This case can't occur in C, but can in Ada if we have
&& (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
&& MEM_ALIGN (op0) == GET_MODE_ALIGNMENT (mode1))
{
- rtx temp = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
-
- if (GET_CODE (XEXP (temp, 0)) == REG)
- op0 = temp;
- else
- op0 = (replace_equiv_address
- (op0,
- force_reg (GET_MODE (XEXP (temp, 0)),
- XEXP (temp, 0))));
+ op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT);
bitpos = 0;
}
return op0;
}
- op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, 0);
+ op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier);
if (GET_MODE (op0) == mode)
return op0;
/* If OP0 is a constant, just convert it into the proper mode. */
if (CONSTANT_P (op0))
- return
- convert_modes (mode, TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))),
- op0, TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))));
+ {
+ tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
+ enum machine_mode inner_mode = TYPE_MODE (inner_type);
+
+ if (modifier == EXPAND_INITIALIZER)
+ return simplify_gen_subreg (mode, op0, inner_mode,
+ subreg_lowpart_offset (mode,
+ inner_mode));
+ else
+ return convert_modes (mode, inner_mode, op0,
+ TREE_UNSIGNED (inner_type));
+ }
if (modifier == EXPAND_INITIALIZER)
return gen_rtx_fmt_e (unsignedp ? ZERO_EXTEND : SIGN_EXTEND, mode, op0);
indexed address, for machines that support that. */
if (modifier == EXPAND_SUM && mode == ptr_mode
- && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
- && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
+ && host_integerp (TREE_OPERAND (exp, 1), 0))
{
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode,
EXPAND_SUM);
- /* Apply distributive law if OP0 is x+c. */
- if (GET_CODE (op0) == PLUS
- && GET_CODE (XEXP (op0, 1)) == CONST_INT)
- return
- gen_rtx_PLUS
- (mode,
- gen_rtx_MULT
- (mode, XEXP (op0, 0),
- GEN_INT (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)))),
- GEN_INT (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))
- * INTVAL (XEXP (op0, 1))));
+ /* If we knew for certain that this is arithmetic for an array
+ reference, and we knew the bounds of the array, then we could
+ apply the distributive law across (PLUS X C) for constant C.
+ Without such knowledge, we risk overflowing the computation
+ when both X and C are large, but X+C isn't. */
+ /* ??? Could perhaps special-case EXP being unsigned and C being
+ positive. In that case we are certain that X+C is no smaller
+ than X and so the transformed expression will overflow iff the
+ original would have. */
if (GET_CODE (op0) != REG)
op0 = force_operand (op0, NULL_RTX);
return
gen_rtx_MULT (mode, op0,
- GEN_INT (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1))));
+ GEN_INT (tree_low_cst (TREE_OPERAND (exp, 1), 0)));
}
if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
/* Put the AND last so it can combine with more things. */
if (bitnum != TYPE_PRECISION (type) - 1)
- op0 = expand_and (op0, const1_rtx, subtarget);
+ op0 = expand_and (mode, op0, const1_rtx, subtarget);
return op0;
}