#include "insn-flags.h"
#include "insn-codes.h"
-/* Return an rtx for the sum of X and the integer C. */
+/* Return an rtx for the sum of X and the integer C.
+
+ This fucntion should be used via the `plus_constant' macro. */
rtx
-plus_constant (x, c)
+plus_constant_wide (x, c)
register rtx x;
- register int c;
+ register HOST_WIDE_INT c;
{
register RTX_CODE code;
register enum machine_mode mode;
switch (code)
{
case CONST_INT:
- return gen_rtx (CONST_INT, VOIDmode, (INTVAL (x) + c));
+ return GEN_INT (INTVAL (x) + c);
case CONST_DOUBLE:
{
- int l1 = CONST_DOUBLE_LOW (x);
- int h1 = CONST_DOUBLE_HIGH (x);
- int l2 = c;
- int h2 = c < 0 ? ~0 : 0;
- int lv, hv;
+ HOST_WIDE_INT l1 = CONST_DOUBLE_LOW (x);
+ HOST_WIDE_INT h1 = CONST_DOUBLE_HIGH (x);
+ HOST_WIDE_INT l2 = c;
+ HOST_WIDE_INT h2 = c < 0 ? ~0 : 0;
+ HOST_WIDE_INT lv, hv;
add_double (l1, h1, l2, h2, &lv, &hv);
Look for constant term in the sum and combine
with C. For an integer constant term, we make a combined
integer. For a constant term that is not an explicit integer,
- we cannot really combine, but group them together anyway. */
- if (GET_CODE (XEXP (x, 0)) == CONST_INT)
- {
- c += INTVAL (XEXP (x, 0));
- x = XEXP (x, 1);
- }
- else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
- {
- c += INTVAL (XEXP (x, 1));
- x = XEXP (x, 0);
- }
+ we cannot really combine, but group them together anyway.
+
+ Use a recursive call in case the remaining operand is something
+ that we handle specially, such as a SYMBOL_REF. */
+
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ return plus_constant (XEXP (x, 0), c + INTVAL (XEXP (x, 1)));
else if (CONSTANT_P (XEXP (x, 0)))
return gen_rtx (PLUS, mode,
plus_constant (XEXP (x, 0), c),
}
if (c != 0)
- x = gen_rtx (PLUS, mode, x, gen_rtx (CONST_INT, VOIDmode, c));
+ x = gen_rtx (PLUS, mode, x, GEN_INT (c));
if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
return x;
return x;
}
-/* This is the same a `plus_constant', except that it handles LO_SUM. */
+/* This is the same as `plus_constant', except that it handles LO_SUM.
+
+ This function should be used via the `plus_constant_for_output' macro. */
rtx
-plus_constant_for_output (x, c)
+plus_constant_for_output_wide (x, c)
register rtx x;
- register int c;
+ register HOST_WIDE_INT c;
{
register RTX_CODE code = GET_CODE (x);
register enum machine_mode mode = GET_MODE (x);
tree exp;
{
return expand_expr (size_in_bytes (TREE_TYPE (exp)),
- 0, TYPE_MODE (sizetype), 0);
+ NULL_RTX, TYPE_MODE (sizetype), 0);
}
\f
/* Return a copy of X in which all memory references
rtx y = eliminate_constant_term (x, &constant_term);
if (constant_term == const0_rtx
|| ! memory_address_p (mode, y))
- return force_operand (x, 0);
+ return force_operand (x, NULL_RTX);
y = gen_rtx (PLUS, GET_MODE (x), copy_to_reg (y), constant_term);
if (! memory_address_p (mode, y))
- return force_operand (x, 0);
+ return force_operand (x, NULL_RTX);
return y;
}
if (GET_CODE (x) == MULT || GET_CODE (x) == MINUS)
- return force_operand (x, 0);
+ return force_operand (x, NULL_RTX);
/* If we have a register that's an invalid address,
it must be a hard reg of the wrong class. Copy it to a pseudo. */
if (general_operand (x, Pmode))
return force_reg (Pmode, x);
else
- return force_operand (x, 0);
+ return force_operand (x, NULL_RTX);
}
return x;
}
and that X can be substituted for it. */
if (CONSTANT_P (x))
{
- rtx note = find_reg_note (insn, REG_EQUAL, 0);
+ rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
if (note)
XEXP (note, 0) = x;
{
int new = (INTVAL (size) + align - 1) / align * align;
if (INTVAL (size) != new)
- size = gen_rtx (CONST_INT, VOIDmode, new);
+ size = GEN_INT (new);
}
else
{
- size = expand_divmod (0, CEIL_DIV_EXPR, Pmode, size,
- gen_rtx (CONST_INT, VOIDmode, align),
- 0, 1);
- size = expand_mult (Pmode, size,
- gen_rtx (CONST_INT, VOIDmode, align),
- 0, 1);
+ size = expand_divmod (0, CEIL_DIV_EXPR, Pmode, size, GEN_INT (align),
+ NULL_RTX, 1);
+ size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1);
}
#endif /* STACK_BOUNDARY */
return size;
abort ();
}
+ if (sa != 0)
+ sa = validize_mem (sa);
+
if (after)
- emit_insn_after (fcn (sa, stack_pointer_rtx), after);
+ {
+ rtx seq;
+
+ start_sequence ();
+ emit_insn (fcn (sa, stack_pointer_rtx));
+ seq = gen_sequence ();
+ end_sequence ();
+ emit_insn_after (seq, after);
+ }
else
emit_insn (fcn (sa, stack_pointer_rtx));
}
#endif
}
+ if (sa != 0)
+ sa = validize_mem (sa);
+
if (after)
- emit_insn_after (fcn (stack_pointer_rtx, sa), after);
+ {
+ rtx seq;
+
+ start_sequence ();
+ emit_insn (fcn (stack_pointer_rtx, sa));
+ seq = gen_sequence ();
+ end_sequence ();
+ emit_insn_after (seq, after);
+ }
else
emit_insn (fcn (stack_pointer_rtx, sa));
}
#ifdef MUST_ALIGN
- if (GET_CODE (size) == CONST_INT)
- size = gen_rtx (CONST_INT, VOIDmode,
- INTVAL (size) + (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1));
- else
- size = expand_binop (Pmode, add_optab, size,
- gen_rtx (CONST_INT, VOIDmode,
- BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1),
- 0, 1, OPTAB_LIB_WIDEN);
+ if (known_align % BIGGEST_ALIGNMENT != 0)
+ {
+ if (GET_CODE (size) == CONST_INT)
+ size = GEN_INT (INTVAL (size)
+ + (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1));
+ else
+ size = expand_binop (Pmode, add_optab, size,
+ GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1),
+ NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ }
#endif
#ifdef SETJMP_VIA_SAVE_AREA
{
rtx dynamic_offset
= expand_binop (Pmode, sub_optab, virtual_stack_dynamic_rtx,
- stack_pointer_rtx, 0, 1, OPTAB_LIB_WIDEN);
+ stack_pointer_rtx, NULL_RTX, 1, OPTAB_LIB_WIDEN);
size = expand_binop (Pmode, add_optab, size, dynamic_offset,
- 0, 1, OPTAB_LIB_WIDEN);
+ NULL_RTX, 1, OPTAB_LIB_WIDEN);
}
#endif /* SETJMP_VIA_SAVE_AREA */
momentarily mis-aligning the stack. */
#ifdef STACK_BOUNDARY
+#ifndef SETJMP_VIA_SAVE_AREA /* If we added a variable amount to SIZE,
+ we can no longer assume it is aligned. */
if (known_align % STACK_BOUNDARY != 0)
+#endif
size = round_push (size);
#endif
|| REGNO (target) < FIRST_PSEUDO_REGISTER)
target = gen_reg_rtx (Pmode);
+ mark_reg_pointer (target);
+
#ifndef STACK_GROWS_DOWNWARD
emit_move_insn (target, virtual_stack_dynamic_rtx);
#endif
if (known_align % BIGGEST_ALIGNMENT != 0)
{
target = expand_divmod (0, CEIL_DIV_EXPR, Pmode, target,
- gen_rtx (CONST_INT, VOIDmode,
- BIGGEST_ALIGNMENT / BITS_PER_UNIT),
- 0, 1);
+ GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT),
+ NULL_RTX, 1);
target = expand_mult (Pmode, target,
- gen_rtx (CONST_INT, VOIDmode,
- BIGGEST_ALIGNMENT / BITS_PER_UNIT),
- 0, 1);
+ GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT),
+ NULL_RTX, 1);
}
#endif