/* Total space needed so far for args on the stack,
given as a constant and a tree-expression. */
struct args_size stack_args_size;
+ HOST_WIDE_INT extra_pretend_bytes = 0;
tree fntype = TREE_TYPE (fndecl);
tree fnargs = DECL_ARGUMENTS (fndecl), orig_fnargs;
/* This is used for the arg pointer when referring to stack args. */
fnargs = split_complex_args (fnargs);
#ifdef REG_PARM_STACK_SPACE
-#ifdef MAYBE_REG_PARM_STACK_SPACE
- reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
-#else
reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
#endif
-#endif
#ifdef INIT_CUMULATIVE_INCOMING_ARGS
INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX);
partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
passed_type, named_arg);
if (partial
-#ifndef MAYBE_REG_PARM_STACK_SPACE
/* The caller might already have allocated stack space
for the register parameters. */
- && reg_parm_stack_space == 0
-#endif
- )
+ && reg_parm_stack_space == 0)
{
/* Part of this argument is passed in registers and part
is passed on the stack. Ask the prologue code to extend
bits. We must preserve this invariant by rounding
CURRENT_FUNCTION_PRETEND_ARGS_SIZE up to a stack
boundary. */
+
+ /* We assume at most one partial arg, and it must be the first
+ argument on the stack. */
+ if (extra_pretend_bytes || current_function_pretend_args_size)
+ abort ();
+
pretend_bytes = partial * UNITS_PER_WORD;
current_function_pretend_args_size
= CEIL_ROUND (pretend_bytes, STACK_BYTES);
- /* If PRETEND_BYTES != CURRENT_FUNCTION_PRETEND_ARGS_SIZE,
- insert the padding before the start of the first pretend
- argument. */
- stack_args_size.constant
- = (current_function_pretend_args_size - pretend_bytes);
+ /* We want to align relative to the actual stack pointer, so
+ don't include this in the stack size until later. */
+ extra_pretend_bytes = current_function_pretend_args_size;
}
}
#endif
locate_and_pad_parm (promoted_mode, passed_type, in_regs,
entry_parm ? partial : 0, fndecl,
&stack_args_size, &locate);
+ /* Adjust offsets to include pretend args, unless this is the
+ split arg. */
+ if (pretend_bytes == 0)
+ {
+ locate.slot_offset.constant += extra_pretend_bytes;
+ locate.offset.constant += extra_pretend_bytes;
+ }
{
rtx offset_rtx;
if (entry_parm == stack_parm
|| (GET_CODE (entry_parm) == PARALLEL
&& XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
-#if defined (REG_PARM_STACK_SPACE) && ! defined (MAYBE_REG_PARM_STACK_SPACE)
+#if defined (REG_PARM_STACK_SPACE)
/* On some machines, even if a parm value arrives in a register
- there is still an (uninitialized) stack slot allocated for it.
-
- ??? When MAYBE_REG_PARM_STACK_SPACE is defined, we can't tell
- whether this parameter already has a stack slot allocated,
- because an arg block exists only if current_function_args_size
- is larger than some threshold, and we haven't calculated that
- yet. So, for now, we just assume that stack slots never exist
- in this case. */
+ there is still an (uninitialized) stack slot allocated
+ for it. */
|| REG_PARM_STACK_SPACE (fndecl) > 0
#endif
)
{
- stack_args_size.constant += pretend_bytes + locate.size.constant;
+ stack_args_size.constant += locate.size.constant;
if (locate.size.var)
ADD_PARM_SIZE (stack_args_size, locate.size.var);
}
{
if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE)
{
- rtx tmp;
-
- SET_DECL_RTL (parm,
- gen_rtx_CONCAT (DECL_MODE (parm),
- DECL_RTL (fnargs),
- DECL_RTL (TREE_CHAIN (fnargs))));
- tmp = gen_rtx_CONCAT (DECL_MODE (parm),
- DECL_INCOMING_RTL (fnargs),
- DECL_INCOMING_RTL (TREE_CHAIN (fnargs)));
+ rtx tmp, real, imag;
+ enum machine_mode inner = GET_MODE_INNER (DECL_MODE (parm));
+
+ real = DECL_RTL (fnargs);
+ imag = DECL_RTL (TREE_CHAIN (fnargs));
+ if (inner != GET_MODE (real))
+ {
+ real = gen_lowpart_SUBREG (inner, real);
+ imag = gen_lowpart_SUBREG (inner, imag);
+ }
+ tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
+ SET_DECL_RTL (parm, tmp);
+
+ real = DECL_INCOMING_RTL (fnargs);
+ imag = DECL_INCOMING_RTL (TREE_CHAIN (fnargs));
+ if (inner != GET_MODE (real))
+ {
+ real = gen_lowpart_SUBREG (inner, real);
+ imag = gen_lowpart_SUBREG (inner, imag);
+ }
+ tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
set_decl_incoming_rtl (parm, tmp);
fnargs = TREE_CHAIN (fnargs);
}
last_parm_insn = get_last_insn ();
+ /* We have aligned all the args, so add space for the pretend args. */
+ stack_args_size.constant += extra_pretend_bytes;
current_function_args_size = stack_args_size.constant;
/* Adjust function incoming argument size for alignment and
minimum length. */
#ifdef REG_PARM_STACK_SPACE
-#ifndef MAYBE_REG_PARM_STACK_SPACE
current_function_args_size = MAX (current_function_args_size,
REG_PARM_STACK_SPACE (fndecl));
#endif
-#endif
current_function_args_size
= ((current_function_args_size + STACK_BYTES - 1)
int part_size_in_regs;
#ifdef REG_PARM_STACK_SPACE
-#ifdef MAYBE_REG_PARM_STACK_SPACE
- reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
-#else
reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
-#endif
/* If we have found a stack parm before we reach the end of the
area reserved for registers, skip that area. */
flow.c that the entire aggregate was initialized.
Unions are troublesome because members may be shorter. */
&& ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
- && DECL_RTL (decl) != 0
+ && DECL_RTL_SET_P (decl)
&& GET_CODE (DECL_RTL (decl)) == REG
/* Global optimizations can make it difficult to determine if a
particular variable has been initialized. However, a VAR_DECL
decl, decl);
if (extra_warnings
&& TREE_CODE (decl) == VAR_DECL
- && DECL_RTL (decl) != 0
+ && DECL_RTL_SET_P (decl)
&& GET_CODE (DECL_RTL (decl)) == REG
&& regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
warning ("%Jvariable '%D' might be clobbered by `longjmp' or `vfork'",
/* If this is a binary operation between a register we have been tracking
and a constant, see if we can compute a new constant value. */
- else if ((GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == 'c'
- || GET_RTX_CLASS (GET_CODE (SET_SRC (x))) == '2')
+ else if (ARITHMETIC_P (SET_SRC (x))
&& GET_CODE (XEXP (SET_SRC (x), 0)) == REG
&& REGNO (XEXP (SET_SRC (x), 0)) < FIRST_PSEUDO_REGISTER
&& p->const_equiv[REGNO (XEXP (SET_SRC (x), 0))] != 0