#define PUSH_ARGS_REVERSED 0
#endif
+#ifndef STACK_POINTER_OFFSET
+#define STACK_POINTER_OFFSET 0
+#endif
+
/* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */
#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
args = (struct arg_data *) alloca (num_actuals * sizeof (struct arg_data));
memset ((char *) args, 0, num_actuals * sizeof (struct arg_data));
- /* Build up entries inthe ARGS array, compute the size of the arguments
- into ARGS_SIZE, etc. */
+ /* Build up entries in the ARGS array, compute the size of the
+ arguments into ARGS_SIZE, etc. */
initialize_argument_information (num_actuals, args, &args_size,
n_named_args, actparms, fndecl,
&args_so_far, reg_parm_stack_space,
#endif
#endif
- /* No library functions can throw. */
+ /* By default, library functions can not throw. */
flags = ECF_NOTHROW;
- if (fn_type == LCT_CONST_MAKE_BLOCK)
- flags |= ECF_CONST;
- else if (fn_type == LCT_PURE_MAKE_BLOCK)
- flags |= ECF_PURE;
- else if (fn_type == LCT_NORETURN)
- flags |= ECF_NORETURN;
+ switch (fn_type)
+ {
+ case LCT_NORMAL:
+ case LCT_CONST:
+ case LCT_PURE:
+ /* Nothing to do here. */
+ break;
+ case LCT_CONST_MAKE_BLOCK:
+ flags |= ECF_CONST;
+ break;
+ case LCT_PURE_MAKE_BLOCK:
+ flags |= ECF_PURE;
+ break;
+ case LCT_NORETURN:
+ flags |= ECF_NORETURN;
+ break;
+ case LCT_THROW:
+ flags = ECF_NORETURN;
+ break;
+ }
fun = orgfun;
#ifdef PREFERRED_STACK_BOUNDARY
highest_outgoing_arg_in_use - initial_highest_arg_in_use);
needed = 0;
- /* The address of the outgoing argument list must not be copied to a
- register here, because argblock would be left pointing to the
- wrong place after the call to allocate_dynamic_stack_space below. */
+ /* We must be careful to use virtual regs before they're instantiated,
+ and real regs afterwards. Loop optimization, for example, can create
+ new libcalls after we've instantiated the virtual regs, and if we
+ use virtuals anyway, they won't match the rtl patterns. */
- argblock = virtual_outgoing_args_rtx;
+ if (virtuals_instantiated)
+ argblock = plus_constant (stack_pointer_rtx, STACK_POINTER_OFFSET);
+ else
+ argblock = virtual_outgoing_args_rtx;
}
else
{
{
rtx size_rtx1 = GEN_INT (reg_parm_stack_space - arg->offset.constant);
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx1,
- TYPE_ALIGN (TREE_TYPE (pval)) / BITS_PER_UNIT,
- partial, reg, excess, argblock,
- ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
+ TYPE_ALIGN (TREE_TYPE (pval)), partial, reg,
+ excess, argblock, ARGS_SIZE_RTX (arg->offset),
+ reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad));
size_rtx = GEN_INT (INTVAL(size_rtx) - reg_parm_stack_space);