/* Subroutines for manipulating rtx's in semantically interesting ways.
- Copyright (C) 1987, 91, 94-97, 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1991, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
#endif
-static rtx break_out_memory_refs PROTO((rtx));
-static void emit_stack_probe PROTO((rtx));
+static rtx break_out_memory_refs PARAMS ((rtx));
+static void emit_stack_probe PARAMS ((rtx));
/* Truncate and perhaps sign-extend C as appropriate for MODE. */
if (oldx == x)
return x;
else if (GET_CODE (x) == REG)
- mark_reg_pointer (x, 1);
+ mark_reg_pointer (x, BITS_PER_UNIT);
else if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
- mark_reg_pointer (XEXP (x, 0), 1);
+ mark_reg_pointer (XEXP (x, 0), BITS_PER_UNIT);
/* OLDX may have been the address on a temporary. Update the address
to indicate that X is now used. */
if (adjust == const0_rtx)
return;
+ /* We expect all variable sized adjustments to be multiple of
+ PREFERRED_STACK_BOUNDARY. */
+ if (GET_CODE (adjust) == CONST_INT)
+ stack_pointer_delta -= INTVAL (adjust);
+
temp = expand_binop (Pmode,
#ifdef STACK_GROWS_DOWNWARD
add_optab,
if (adjust == const0_rtx)
return;
+ /* We expect all variable sized adjustments to be multiple of
+ PREFERRED_STACK_BOUNDARY. */
+ if (GET_CODE (adjust) == CONST_INT)
+ stack_pointer_delta += INTVAL (adjust);
+
temp = expand_binop (Pmode,
#ifdef STACK_GROWS_DOWNWARD
sub_optab,
{
rtx sa = *psave;
/* The default is that we use a move insn and save in a Pmode object. */
- rtx (*fcn) PROTO ((rtx, rtx)) = gen_move_insn;
+ rtx (*fcn) PARAMS ((rtx, rtx)) = gen_move_insn;
enum machine_mode mode = STACK_SAVEAREA_MODE (save_level);
/* See if this machine has anything special to do for this kind of save. */
rtx sa;
{
/* The default is that we use a move insn. */
- rtx (*fcn) PROTO ((rtx, rtx)) = gen_move_insn;
+ rtx (*fcn) PARAMS ((rtx, rtx)) = gen_move_insn;
/* See if this machine has anything special to do for this kind of save. */
switch (save_level)
if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode)
size = convert_to_mode (Pmode, size, 1);
+ /* We can't attempt to minimize alignment necessary, because we don't
+ know the final value of preferred_stack_boundary yet while executing
+ this code. */
+#ifdef PREFERRED_STACK_BOUNDARY
+ cfun->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
+#endif
+
/* We will need to ensure that the address we return is aligned to
BIGGEST_ALIGNMENT. If STACK_DYNAMIC_OFFSET is defined, we don't
always know its final value at this point in the compilation (it
do_pending_stack_adjust ();
+ /* We ought to be called always on the toplevel and stack ought to be aligned
+ propertly. */
+#ifdef PREFERRED_STACK_BOUNDARY
+ if (stack_pointer_delta % (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT))
+ abort ();
+#endif
+
/* If needed, check that we have the required amount of stack. Take into
account what has already been checked. */
if (flag_stack_check && ! STACK_CHECK_BUILTIN)
|| REGNO (target) < FIRST_PSEUDO_REGISTER)
target = gen_reg_rtx (Pmode);
- mark_reg_pointer (target, known_align / BITS_PER_UNIT);
+ mark_reg_pointer (target, known_align);
/* Perform the required allocation from the stack. Some systems do
this differently than simply incrementing/decrementing from the
emit_move_insn (target, virtual_stack_dynamic_rtx);
#endif
size = convert_modes (Pmode, ptr_mode, size, 1);
+
+ /* Check stack bounds if necessary. */
+ if (current_function_limit_stack)
+ {
+ rtx available;
+ rtx space_available = gen_label_rtx ();
+#ifdef STACK_GROWS_DOWNWARD
+ available = expand_binop (Pmode, sub_optab,
+ stack_pointer_rtx, stack_limit_rtx,
+ NULL_RTX, 1, OPTAB_WIDEN);
+#else
+ available = expand_binop (Pmode, sub_optab,
+ stack_limit_rtx, stack_pointer_rtx,
+ NULL_RTX, 1, OPTAB_WIDEN);
+#endif
+ emit_cmp_and_jump_insns (available, size, GEU, NULL_RTX, Pmode, 1,
+ 0, space_available);
+#ifdef HAVE_trap
+ if (HAVE_trap)
+ emit_insn (gen_trap ());
+ else
+#endif
+ error ("stack limits not supported on this target");
+ emit_barrier ();
+ emit_label (space_available);
+ }
+
anti_adjust_stack (size);
#ifdef SETJMP_VIA_SAVE_AREA
if (setjmpless_size != NULL_RTX)
emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
emit_label (end_lab);
- /* If will be doing stupid optimization, show test_addr is still live. */
- if (obey_regdecls)
- emit_insn (gen_rtx_USE (VOIDmode, test_addr));
-
emit_stack_probe (last_addr);
}
}
in which a scalar value of data type VALTYPE
was returned by a function call to function FUNC.
FUNC is a FUNCTION_DECL node if the precise function is known,
- otherwise 0. */
+ otherwise 0.
+ OUTGOING is 1 if on a machine with register windows this function
+ should return the register in which the function will put its result
+ and 0 otherwise. */
rtx
-hard_function_value (valtype, func)
+hard_function_value (valtype, func, outgoing)
tree valtype;
tree func ATTRIBUTE_UNUSED;
+ int outgoing ATTRIBUTE_UNUSED;
{
- rtx val = FUNCTION_VALUE (valtype, func);
+ rtx val;
+
+#ifdef FUNCTION_OUTGOING_VALUE
+ if (outgoing)
+ val = FUNCTION_OUTGOING_VALUE (valtype, func);
+ else
+#endif
+ val = FUNCTION_VALUE (valtype, func);
+
if (GET_CODE (val) == REG
&& GET_MODE (val) == BLKmode)
{
- int bytes = int_size_in_bytes (valtype);
+ unsigned HOST_WIDE_INT bytes = int_size_in_bytes (valtype);
enum machine_mode tmpmode;
+
for (tmpmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
tmpmode != VOIDmode;
tmpmode = GET_MODE_WIDER_MODE (tmpmode))