return c;
}
-/* Return an rtx for the sum of X and the integer C.
-
- This function should be used via the `plus_constant' macro. */
+/* Return an rtx for the sum of X and the integer C. */
rtx
-plus_constant_wide (rtx x, HOST_WIDE_INT c)
+plus_constant (rtx x, HOST_WIDE_INT c)
{
RTX_CODE code;
rtx y;
rtx
expr_size (tree exp)
{
- tree size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lang_hooks.expr_size (exp), exp);
+ tree size;
+
+ if (TREE_CODE (exp) == WITH_SIZE_EXPR)
+ size = TREE_OPERAND (exp, 1);
+ else
+ size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (lang_hooks.expr_size (exp), exp);
return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
}
HOST_WIDE_INT
int_expr_size (tree exp)
{
- tree t = lang_hooks.expr_size (exp);
-
- if (t == 0
- || TREE_CODE (t) != INTEGER_CST
- || TREE_OVERFLOW (t)
- || TREE_INT_CST_HIGH (t) != 0
- /* If the result would appear negative, it's too big to represent. */
- || (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
+ tree size;
+
+ if (TREE_CODE (exp) == WITH_SIZE_EXPR)
+ size = TREE_OPERAND (exp, 1);
+ else
+ size = lang_hooks.expr_size (exp);
+
+ if (size == 0 || !host_integerp (size, 0))
return -1;
- return TREE_INT_CST_LOW (t);
+ return tree_low_cst (size, 0);
}
\f
/* Return a copy of X in which all memory references
static rtx
break_out_memory_refs (rtx x)
{
- if (GET_CODE (x) == MEM
+ if (MEM_P (x)
|| (CONSTANT_P (x) && CONSTANT_ADDRESS_P (x)
&& GET_MODE (x) != VOIDmode))
x = force_reg (GET_MODE (x), x);
rtx
copy_all_regs (rtx x)
{
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
{
if (REGNO (x) != FRAME_POINTER_REGNUM
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
)
x = copy_to_reg (x);
}
- else if (GET_CODE (x) == MEM)
+ else if (MEM_P (x))
x = copy_to_reg (x);
else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
|| GET_CODE (x) == MULT)
{
rtx oldx = x;
- if (GET_CODE (x) == ADDRESSOF)
- return x;
-
x = convert_memory_address (Pmode, x);
/* By passing constant addresses through registers
if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x))
x = force_reg (Pmode, x);
- /* Accept a QUEUED that refers to a REG
- even though that isn't a valid address.
- On attempting to put this in an insn we will call protect_from_queue
- which will turn it into a REG, which is valid. */
- else if (GET_CODE (x) == QUEUED
- && GET_CODE (QUEUED_VAR (x)) == REG)
- ;
-
/* We get better cse by rejecting indirect addressing at this stage.
Let the combiner create indirect addresses where appropriate.
For now, generate the code so that the subexpressions useful to share
are visible. But not if cse won't be done! */
else
{
- if (! cse_not_expected && GET_CODE (x) != REG)
+ if (! cse_not_expected && !REG_P (x))
x = break_out_memory_refs (x);
/* At this point, any valid address is accepted. */
- GO_IF_LEGITIMATE_ADDRESS (mode, x, win);
+ if (memory_address_p (mode, x))
+ goto win;
/* If it was valid before but breaking out memory refs invalidated it,
use it the old way. */
/* 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. */
- else if (GET_CODE (x) == REG)
+ else if (REG_P (x))
x = copy_to_reg (x);
/* Last resort: copy the value to a register, since
win2:
x = oldx;
win:
- if (flag_force_addr && ! cse_not_expected && GET_CODE (x) != REG
+ if (flag_force_addr && ! cse_not_expected && !REG_P (x)
/* Don't copy an addr via a reg if it is one of our stack slots. */
&& ! (GET_CODE (x) == PLUS
&& (XEXP (x, 0) == virtual_stack_vars_rtx
a reg as a pointer if we have REG or REG + CONST_INT. */
if (oldx == x)
return x;
- else if (GET_CODE (x) == REG)
+ else if (REG_P (x))
mark_reg_pointer (x, BITS_PER_UNIT);
else if (GET_CODE (x) == PLUS
- && GET_CODE (XEXP (x, 0)) == REG
+ && REG_P (XEXP (x, 0))
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
mark_reg_pointer (XEXP (x, 0), BITS_PER_UNIT);
rtx
validize_mem (rtx ref)
{
- if (GET_CODE (ref) != MEM)
+ if (!MEM_P (ref))
return ref;
if (! (flag_force_addr && CONSTANT_ADDRESS_P (XEXP (ref, 0)))
&& memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
rtx
stabilize (rtx x)
{
- if (GET_CODE (x) != MEM
+ if (!MEM_P (x)
|| ! rtx_unstable_p (XEXP (x, 0)))
return x;
{
rtx temp, insn, set;
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
return x;
if (general_operand (x, mode))
else
{
temp = force_operand (x, NULL_RTX);
- if (GET_CODE (temp) == REG)
+ if (REG_P (temp))
insn = get_last_insn ();
else
{
{
rtx temp;
- if (GET_CODE (x) != MEM || GET_MODE (x) == BLKmode)
+ if (!MEM_P (x) || GET_MODE (x) == BLKmode)
return x;
temp = gen_reg_rtx (GET_MODE (x));
{
rtx temp;
- if (target && GET_CODE (target) == REG)
+ if (target && REG_P (target))
temp = target;
else
temp = gen_reg_rtx (mode);
FOR_CALL is nonzero if this call is promoting args for a call. */
#if defined(PROMOTE_MODE) && !defined(PROMOTE_FUNCTION_MODE)
-#define PROMOTE_FUNCTON_MODE PROMOTE_MODE
+#define PROMOTE_FUNCTION_MODE PROMOTE_MODE
#endif
enum machine_mode
adjust_stack (rtx adjust)
{
rtx temp;
- adjust = protect_from_queue (adjust, 0);
if (adjust == const0_rtx)
return;
anti_adjust_stack (rtx adjust)
{
rtx temp;
- adjust = protect_from_queue (adjust, 0);
if (adjust == const0_rtx)
return;
*psave = sa = gen_reg_rtx (mode);
}
}
- else
- {
- if (mode == VOIDmode || GET_MODE (sa) != mode)
- abort ();
- }
if (after)
{
else
emit_insn (fcn (stack_pointer_rtx, sa));
}
+
+/* Invoke emit_stack_save on the nonlocal_goto_save_area for the current
+ function. This function should be called whenever we allocate or
+ deallocate dynamic stack space. */
+
+void
+update_nonlocal_goto_save_area (void)
+{
+ tree t_save;
+ rtx r_save;
+
+ /* The nonlocal_goto_save_area object is an array of N pointers. The
+ first one is used for the frame pointer save; the rest are sized by
+ STACK_SAVEAREA_MODE. Create a reference to array index 1, the first
+ of the stack save area slots. */
+ t_save = build4 (ARRAY_REF, ptr_type_node, cfun->nonlocal_goto_save_area,
+ integer_one_node, NULL_TREE, NULL_TREE);
+ r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
+
+ emit_stack_save (SAVE_NONLOCAL, &r_save, NULL_RTX);
+}
\f
#ifdef SETJMP_VIA_SAVE_AREA
/* Optimize RTL generated by allocate_dynamic_stack_space for targets
frame, thus causing a crash if a longjmp unwinds to it. */
void
-optimize_save_area_alloca (rtx insns)
+optimize_save_area_alloca (void)
{
rtx insn;
- for (insn = insns; insn; insn = NEXT_INSN(insn))
+ for (insn = get_insns (); insn; insn = NEXT_INSN(insn))
{
rtx note;
- if (GET_CODE (insn) != INSN)
+ if (!NONJUMP_INSN_P (insn))
continue;
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
probe_stack_range (STACK_CHECK_MAX_FRAME_SIZE + STACK_CHECK_PROTECT, size);
/* Don't use a TARGET that isn't a pseudo or is the wrong mode. */
- if (target == 0 || GET_CODE (target) != REG
+ if (target == 0 || !REG_P (target)
|| REGNO (target) < FIRST_PSEUDO_REGISTER
|| GET_MODE (target) != Pmode)
target = gen_reg_rtx (Pmode);
}
/* Record the new stack level for nonlocal gotos. */
- if (nonlocal_goto_handler_slots != 0)
- emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
+ if (cfun->nonlocal_goto_save_area != 0)
+ update_nonlocal_goto_save_area ();
return target;
}
rtx end_lab = gen_label_rtx ();
rtx temp;
- if (GET_CODE (test_addr) != REG
+ if (!REG_P (test_addr)
|| REGNO (test_addr) < FIRST_PSEUDO_REGISTER)
test_addr = force_reg (Pmode, test_addr);
- emit_note (NOTE_INSN_LOOP_BEG);
emit_jump (test_lab);
emit_label (loop_lab);
emit_stack_probe (test_addr);
- emit_note (NOTE_INSN_LOOP_CONT);
-
#ifdef STACK_GROWS_DOWNWARD
#define CMP_OPCODE GTU
temp = expand_binop (Pmode, sub_optab, test_addr, incr, test_addr,
emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE,
NULL_RTX, Pmode, 1, loop_lab);
emit_jump (end_lab);
- emit_note (NOTE_INSN_LOOP_END);
emit_label (end_lab);
emit_stack_probe (last_addr);
#endif
val = FUNCTION_VALUE (valtype, func);
- if (GET_CODE (val) == REG
+ if (REG_P (val)
&& GET_MODE (val) == BLKmode)
{
unsigned HOST_WIDE_INT bytes = int_size_in_bytes (valtype);