Commit e7949876 by Alan Modra Committed by Alan Modra

calls.c (struct arg_data): Move offset, slot_offset, size and alignment_pad to…

calls.c (struct arg_data): Move offset, slot_offset, size and alignment_pad to struct locate_and_pad_arg_data.

	* calls.c (struct arg_data): Move offset, slot_offset, size and
	alignment_pad to struct locate_and_pad_arg_data.  Update all refs.
	(initialize_argument_information): Adjust call to locate_and_pad_parm.
	Delete alignment_pad var.  Don't calculate slot_offset here.
	(emit_library_call_value_1): Delete alignment_pad, offset and size
	vars.  Use struct locate_and_pad_arg_data instead.  Adjust refs.
	Adjust call to locate_and_pad_parm.  Don't tweak arg size for
	partial in-regs here.  Formatting fixes.
	* expr.h (struct locate_and_pad_arg_data): New struct.
	(locate_and_pad_parm): Adjust declaration.
	* function.c (assign_parms): Localize vars.  Use "locate" instead of
	other arg location vars.  Don't invoke FUNCTION_ARG or
	FUNCTION_INCOMING_ARG unless pretend_named is different from
	named_arg.  Heed MUST_PASS_IN_STACK and set up "partial" before
	calling locate_and_pad_parm.  Adjust locate_and_pad_parm call.
	Use slot_offset for stack home of reg parms.  Correct test for
	parm passed in memory.  Formatting fixes.
	(locate_and_pad_parm): Add "partial" to params.  Replace offset_ptr
	arg_size_ptr and alignment pad with "locate".  Set slot_offset here.
	Correct initial_offset_ptr handling.  Localize vars.  Always pad
	locate->offset even when in_regs.

From-SVN: r66383
parent 5ca5a655
2003-05-02 Alan Modra <amodra@bigpond.net.au>
* calls.c (struct arg_data): Move offset, slot_offset, size and
alignment_pad to struct locate_and_pad_arg_data. Update all refs.
(initialize_argument_information): Adjust call to locate_and_pad_parm.
Delete alignment_pad var. Don't calculate slot_offset here.
(emit_library_call_value_1): Delete alignment_pad, offset and size
vars. Use struct locate_and_pad_arg_data instead. Adjust refs.
Adjust call to locate_and_pad_parm. Don't tweak arg size for
partial in-regs here. Formatting fixes.
* expr.h (struct locate_and_pad_arg_data): New struct.
(locate_and_pad_parm): Adjust declaration.
* function.c (assign_parms): Localize vars. Use "locate" instead of
other arg location vars. Don't invoke FUNCTION_ARG or
FUNCTION_INCOMING_ARG unless pretend_named is different from
named_arg. Heed MUST_PASS_IN_STACK and set up "partial" before
calling locate_and_pad_parm. Adjust locate_and_pad_parm call.
Use slot_offset for stack home of reg parms. Correct test for
parm passed in memory. Formatting fixes.
(locate_and_pad_parm): Add "partial" to params. Replace offset_ptr
arg_size_ptr and alignment pad with "locate". Set slot_offset here.
Correct initial_offset_ptr handling. Localize vars. Always pad
locate->offset even when in_regs.
2003-05-02 Nathan Sidwell <nathan@codesourcery.com> 2003-05-02 Nathan Sidwell <nathan@codesourcery.com>
* Makefile.in (TREE_H): Replace location.h with input.h. * Makefile.in (TREE_H): Replace location.h with input.h.
......
...@@ -98,16 +98,8 @@ struct arg_data ...@@ -98,16 +98,8 @@ struct arg_data
even though pass_on_stack is zero, just because FUNCTION_ARG says so. even though pass_on_stack is zero, just because FUNCTION_ARG says so.
pass_on_stack identifies arguments that *cannot* go in registers. */ pass_on_stack identifies arguments that *cannot* go in registers. */
int pass_on_stack; int pass_on_stack;
/* Offset of this argument from beginning of stack-args. */ /* Some fields packaged up for locate_and_pad_parm. */
struct args_size offset; struct locate_and_pad_arg_data locate;
/* Similar, but offset to the start of the stack slot. Different from
OFFSET if this arg pads downward. */
struct args_size slot_offset;
/* Size of this argument on the stack, rounded up for any padding it gets,
parts of the argument passed in registers do not count.
If REG_PARM_STACK_SPACE is defined, then register parms
are counted here as well. */
struct args_size size;
/* Location on the stack at which parameter should be stored. The store /* Location on the stack at which parameter should be stored. The store
has already been done if STACK == VALUE. */ has already been done if STACK == VALUE. */
rtx stack; rtx stack;
...@@ -123,9 +115,6 @@ struct arg_data ...@@ -123,9 +115,6 @@ struct arg_data
word-sized pseudos we made. */ word-sized pseudos we made. */
rtx *aligned_regs; rtx *aligned_regs;
int n_aligned_regs; int n_aligned_regs;
/* The amount that the stack pointer needs to be adjusted to
force alignment for the next argument. */
struct args_size alignment_pad;
}; };
/* A vector of one char per byte of stack space. A byte if nonzero if /* A vector of one char per byte of stack space. A byte if nonzero if
...@@ -1120,7 +1109,6 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args, ...@@ -1120,7 +1109,6 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
/* Count arg position in order args appear. */ /* Count arg position in order args appear. */
int argpos; int argpos;
struct args_size alignment_pad;
int i; int i;
tree p; tree p;
...@@ -1331,39 +1319,14 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args, ...@@ -1331,39 +1319,14 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
#else #else
args[i].reg != 0, args[i].reg != 0,
#endif #endif
fndecl, args_size, &args[i].offset, args[i].pass_on_stack ? 0 : args[i].partial,
&args[i].size, &alignment_pad); fndecl, args_size, &args[i].locate);
#ifndef ARGS_GROW_DOWNWARD
args[i].slot_offset = *args_size;
#endif
args[i].alignment_pad = alignment_pad;
/* If a part of the arg was put into registers,
don't include that part in the amount pushed. */
if (reg_parm_stack_space == 0 && ! args[i].pass_on_stack)
args[i].size.constant -= ((args[i].partial * UNITS_PER_WORD)
/ (PARM_BOUNDARY / BITS_PER_UNIT)
* (PARM_BOUNDARY / BITS_PER_UNIT));
/* Update ARGS_SIZE, the total stack space for args so far. */ /* Update ARGS_SIZE, the total stack space for args so far. */
args_size->constant += args[i].size.constant; args_size->constant += args[i].locate.size.constant;
if (args[i].size.var) if (args[i].locate.size.var)
{ ADD_PARM_SIZE (*args_size, args[i].locate.size.var);
ADD_PARM_SIZE (*args_size, args[i].size.var);
}
/* Since the slot offset points to the bottom of the slot,
we must record it after incrementing if the args grow down. */
#ifdef ARGS_GROW_DOWNWARD
args[i].slot_offset = *args_size;
args[i].slot_offset.constant = -args_size->constant;
if (args_size->var)
SUB_PARM_SIZE (args[i].slot_offset, args_size->var);
#endif
/* Increment ARGS_SO_FAR, which has info about which arg-registers /* Increment ARGS_SO_FAR, which has info about which arg-registers
have been used, etc. */ have been used, etc. */
...@@ -1616,8 +1579,8 @@ compute_argument_addresses (args, argblock, num_actuals) ...@@ -1616,8 +1579,8 @@ compute_argument_addresses (args, argblock, num_actuals)
for (i = 0; i < num_actuals; i++) for (i = 0; i < num_actuals; i++)
{ {
rtx offset = ARGS_SIZE_RTX (args[i].offset); rtx offset = ARGS_SIZE_RTX (args[i].locate.offset);
rtx slot_offset = ARGS_SIZE_RTX (args[i].slot_offset); rtx slot_offset = ARGS_SIZE_RTX (args[i].locate.slot_offset);
rtx addr; rtx addr;
/* Skip this parm if it will not be passed on the stack. */ /* Skip this parm if it will not be passed on the stack. */
...@@ -2060,12 +2023,12 @@ check_sibcall_argument_overlap (insn, arg, mark_stored_args_map) ...@@ -2060,12 +2023,12 @@ check_sibcall_argument_overlap (insn, arg, mark_stored_args_map)
if (mark_stored_args_map) if (mark_stored_args_map)
{ {
#ifdef ARGS_GROW_DOWNWARD #ifdef ARGS_GROW_DOWNWARD
low = -arg->slot_offset.constant - arg->size.constant; low = -arg->locate.slot_offset.constant - arg->locate.size.constant;
#else #else
low = arg->slot_offset.constant; low = arg->locate.slot_offset.constant;
#endif #endif
for (high = low + arg->size.constant; low < high; low++) for (high = low + arg->locate.size.constant; low < high; low++)
SET_BIT (stored_args_map, low); SET_BIT (stored_args_map, low);
} }
return insn != NULL_RTX; return insn != NULL_RTX;
...@@ -3364,7 +3327,7 @@ expand_call (exp, target, ignore) ...@@ -3364,7 +3327,7 @@ expand_call (exp, target, ignore)
emit_move_insn (stack_area, args[i].save_area); emit_move_insn (stack_area, args[i].save_area);
else else
emit_block_move (stack_area, args[i].save_area, emit_block_move (stack_area, args[i].save_area,
GEN_INT (args[i].size.constant), GEN_INT (args[i].locate.size.constant),
BLOCK_OP_CALL_PARM); BLOCK_OP_CALL_PARM);
} }
...@@ -3513,7 +3476,6 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3513,7 +3476,6 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
rtx fun; rtx fun;
int inc; int inc;
int count; int count;
struct args_size alignment_pad;
rtx argblock = 0; rtx argblock = 0;
CUMULATIVE_ARGS args_so_far; CUMULATIVE_ARGS args_so_far;
struct arg struct arg
...@@ -3522,8 +3484,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3522,8 +3484,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
enum machine_mode mode; enum machine_mode mode;
rtx reg; rtx reg;
int partial; int partial;
struct args_size offset; struct locate_and_pad_arg_data locate;
struct args_size size;
rtx save_area; rtx save_area;
}; };
struct arg *argvec; struct arg *argvec;
...@@ -3683,12 +3644,11 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3683,12 +3644,11 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#else #else
argvec[count].reg != 0, argvec[count].reg != 0,
#endif #endif
NULL_TREE, &args_size, &argvec[count].offset, 0, NULL_TREE, &args_size, &argvec[count].locate);
&argvec[count].size, &alignment_pad);
if (argvec[count].reg == 0 || argvec[count].partial != 0 if (argvec[count].reg == 0 || argvec[count].partial != 0
|| reg_parm_stack_space > 0) || reg_parm_stack_space > 0)
args_size.constant += argvec[count].size.constant; args_size.constant += argvec[count].locate.size.constant;
FUNCTION_ARG_ADVANCE (args_so_far, Pmode, (tree) 0, 1); FUNCTION_ARG_ADVANCE (args_so_far, Pmode, (tree) 0, 1);
...@@ -3802,18 +3762,15 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3802,18 +3762,15 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#else #else
argvec[count].reg != 0, argvec[count].reg != 0,
#endif #endif
NULL_TREE, &args_size, &argvec[count].offset, argvec[count].partial,
&argvec[count].size, &alignment_pad); NULL_TREE, &args_size, &argvec[count].locate);
if (argvec[count].size.var) if (argvec[count].locate.size.var)
abort (); abort ();
if (reg_parm_stack_space == 0 && argvec[count].partial)
argvec[count].size.constant -= argvec[count].partial * UNITS_PER_WORD;
if (argvec[count].reg == 0 || argvec[count].partial != 0 if (argvec[count].reg == 0 || argvec[count].partial != 0
|| reg_parm_stack_space > 0) || reg_parm_stack_space > 0)
args_size.constant += argvec[count].size.constant; args_size.constant += argvec[count].locate.size.constant;
FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree) 0, 1); FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree) 0, 1);
} }
...@@ -3951,11 +3908,11 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3951,11 +3908,11 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#ifdef ARGS_GROW_DOWNWARD #ifdef ARGS_GROW_DOWNWARD
/* stack_slot is negative, but we want to index stack_usage_map /* stack_slot is negative, but we want to index stack_usage_map
with positive values. */ with positive values. */
upper_bound = -argvec[argnum].offset.constant + 1; upper_bound = -argvec[argnum].locate.offset.constant + 1;
lower_bound = upper_bound - argvec[argnum].size.constant; lower_bound = upper_bound - argvec[argnum].locate.size.constant;
#else #else
lower_bound = argvec[argnum].offset.constant; lower_bound = argvec[argnum].locate.offset.constant;
upper_bound = lower_bound + argvec[argnum].size.constant; upper_bound = lower_bound + argvec[argnum].locate.size.constant;
#endif #endif
i = lower_bound; i = lower_bound;
...@@ -3968,19 +3925,16 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3968,19 +3925,16 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
if (i < upper_bound) if (i < upper_bound)
{ {
/* We need to make a save area. See what mode we can make /* We need to make a save area. */
it. */ unsigned int size
= argvec[argnum].locate.size.constant * BITS_PER_UNIT;
enum machine_mode save_mode enum machine_mode save_mode
= mode_for_size (argvec[argnum].size.constant = mode_for_size (size, MODE_INT, 1);
* BITS_PER_UNIT, rtx adr
MODE_INT, 1); = plus_constant (argblock,
argvec[argnum].locate.offset.constant);
rtx stack_area rtx stack_area
= gen_rtx_MEM = gen_rtx_MEM (save_mode, memory_address (save_mode, adr));
(save_mode,
memory_address
(save_mode,
plus_constant (argblock,
argvec[argnum].offset.constant)));
argvec[argnum].save_area = gen_reg_rtx (save_mode); argvec[argnum].save_area = gen_reg_rtx (save_mode);
emit_move_insn (argvec[argnum].save_area, stack_area); emit_move_insn (argvec[argnum].save_area, stack_area);
...@@ -3989,8 +3943,9 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -3989,8 +3943,9 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
emit_push_insn (val, mode, NULL_TREE, NULL_RTX, PARM_BOUNDARY, emit_push_insn (val, mode, NULL_TREE, NULL_RTX, PARM_BOUNDARY,
partial, reg, 0, argblock, partial, reg, 0, argblock,
GEN_INT (argvec[argnum].offset.constant), GEN_INT (argvec[argnum].locate.offset.constant),
reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad)); reg_parm_stack_space,
ARGS_SIZE_RTX (argvec[argnum].locate.alignment_pad));
/* Now mark the segment we just used. */ /* Now mark the segment we just used. */
if (ACCUMULATE_OUTGOING_ARGS) if (ACCUMULATE_OUTGOING_ARGS)
...@@ -4195,12 +4150,10 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) ...@@ -4195,12 +4150,10 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
if (argvec[count].save_area) if (argvec[count].save_area)
{ {
enum machine_mode save_mode = GET_MODE (argvec[count].save_area); enum machine_mode save_mode = GET_MODE (argvec[count].save_area);
rtx stack_area rtx adr = plus_constant (argblock,
= gen_rtx_MEM (save_mode, argvec[count].locate.offset.constant);
memory_address rtx stack_area = gen_rtx_MEM (save_mode,
(save_mode, memory_address (save_mode, adr));
plus_constant (argblock,
argvec[count].offset.constant)));
emit_move_insn (stack_area, argvec[count].save_area); emit_move_insn (stack_area, argvec[count].save_area);
} }
...@@ -4327,14 +4280,14 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space) ...@@ -4327,14 +4280,14 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
else else
upper_bound = 0; upper_bound = 0;
lower_bound = upper_bound - arg->size.constant; lower_bound = upper_bound - arg->locate.size.constant;
#else #else
if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS) if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS)
lower_bound = INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1)); lower_bound = INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1));
else else
lower_bound = 0; lower_bound = 0;
upper_bound = lower_bound + arg->size.constant; upper_bound = lower_bound + arg->locate.size.constant;
#endif #endif
i = lower_bound; i = lower_bound;
...@@ -4347,13 +4300,11 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space) ...@@ -4347,13 +4300,11 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
if (i < upper_bound) if (i < upper_bound)
{ {
/* We need to make a save area. See what mode we can make it. */ /* We need to make a save area. */
enum machine_mode save_mode unsigned int size = arg->locate.size.constant * BITS_PER_UNIT;
= mode_for_size (arg->size.constant * BITS_PER_UNIT, MODE_INT, 1); enum machine_mode save_mode = mode_for_size (size, MODE_INT, 1);
rtx stack_area rtx adr = memory_address (save_mode, XEXP (arg->stack_slot, 0));
= gen_rtx_MEM (save_mode, rtx stack_area = gen_rtx_MEM (save_mode, adr);
memory_address (save_mode,
XEXP (arg->stack_slot, 0)));
if (save_mode == BLKmode) if (save_mode == BLKmode)
{ {
...@@ -4481,8 +4432,8 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space) ...@@ -4481,8 +4432,8 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
This can either be done with push or copy insns. */ This can either be done with push or copy insns. */
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX,
PARM_BOUNDARY, partial, reg, used - size, argblock, PARM_BOUNDARY, partial, reg, used - size, argblock,
ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space, ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad)); ARGS_SIZE_RTX (arg->locate.alignment_pad));
/* Unless this is a partially-in-register argument, the argument is now /* Unless this is a partially-in-register argument, the argument is now
in the stack. */ in the stack. */
...@@ -4504,16 +4455,17 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space) ...@@ -4504,16 +4455,17 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
/* Round its size up to a multiple /* Round its size up to a multiple
of the allocation unit for arguments. */ of the allocation unit for arguments. */
if (arg->size.var != 0) if (arg->locate.size.var != 0)
{ {
excess = 0; excess = 0;
size_rtx = ARGS_SIZE_RTX (arg->size); size_rtx = ARGS_SIZE_RTX (arg->locate.size);
} }
else else
{ {
/* PUSH_ROUNDING has no effect on us, because /* PUSH_ROUNDING has no effect on us, because
emit_push_insn for BLKmode is careful to avoid it. */ emit_push_insn for BLKmode is careful to avoid it. */
excess = (arg->size.constant - int_size_in_bytes (TREE_TYPE (pval)) excess = (arg->locate.size.constant
- int_size_in_bytes (TREE_TYPE (pval))
+ partial * UNITS_PER_WORD); + partial * UNITS_PER_WORD);
size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)), size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)),
NULL_RTX, TYPE_MODE (sizetype), 0); NULL_RTX, TYPE_MODE (sizetype), 0);
...@@ -4527,7 +4479,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space) ...@@ -4527,7 +4479,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
PARM_BOUNDARY, but the actual argument isn't. */ PARM_BOUNDARY, but the actual argument isn't. */
if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward) if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
{ {
if (arg->size.var) if (arg->locate.size.var)
parm_align = BITS_PER_UNIT; parm_align = BITS_PER_UNIT;
else if (excess) else if (excess)
{ {
...@@ -4539,7 +4491,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space) ...@@ -4539,7 +4491,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM) if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM)
{ {
/* emit_push_insn might not work properly if arg->value and /* emit_push_insn might not work properly if arg->value and
argblock + arg->offset areas overlap. */ argblock + arg->locate.offset areas overlap. */
rtx x = arg->value; rtx x = arg->value;
int i = 0; int i = 0;
...@@ -4553,17 +4505,17 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space) ...@@ -4553,17 +4505,17 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
i = INTVAL (XEXP (XEXP (x, 0), 1)); i = INTVAL (XEXP (XEXP (x, 0), 1));
/* expand_call should ensure this */ /* expand_call should ensure this */
if (arg->offset.var || GET_CODE (size_rtx) != CONST_INT) if (arg->locate.offset.var || GET_CODE (size_rtx) != CONST_INT)
abort (); abort ();
if (arg->offset.constant > i) if (arg->locate.offset.constant > i)
{ {
if (arg->offset.constant < i + INTVAL (size_rtx)) if (arg->locate.offset.constant < i + INTVAL (size_rtx))
sibcall_failure = 1; sibcall_failure = 1;
} }
else if (arg->offset.constant < i) else if (arg->locate.offset.constant < i)
{ {
if (i < arg->offset.constant + INTVAL (size_rtx)) if (i < arg->locate.offset.constant + INTVAL (size_rtx))
sibcall_failure = 1; sibcall_failure = 1;
} }
} }
...@@ -4571,8 +4523,8 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space) ...@@ -4571,8 +4523,8 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx, emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
parm_align, partial, reg, excess, argblock, parm_align, partial, reg, excess, argblock,
ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space, ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad)); ARGS_SIZE_RTX (arg->locate.alignment_pad));
/* Unless this is a partially-in-register argument, the argument is now /* Unless this is a partially-in-register argument, the argument is now
in the stack. in the stack.
......
...@@ -63,6 +63,8 @@ enum expand_modifier {EXPAND_NORMAL = 0, EXPAND_STACK_PARM = 2, EXPAND_SUM, ...@@ -63,6 +63,8 @@ enum expand_modifier {EXPAND_NORMAL = 0, EXPAND_STACK_PARM = 2, EXPAND_SUM,
more information. */ more information. */
#define OK_DEFER_POP (inhibit_defer_pop -= 1) #define OK_DEFER_POP (inhibit_defer_pop -= 1)
enum direction {none, upward, downward};
#ifdef TREE_CODE /* Don't lose if tree.h not included. */ #ifdef TREE_CODE /* Don't lose if tree.h not included. */
/* Structure to record the size of a sequence of arguments /* Structure to record the size of a sequence of arguments
as the sum of a tree-expression and a constant. This structure is as the sum of a tree-expression and a constant. This structure is
...@@ -74,6 +76,24 @@ struct args_size ...@@ -74,6 +76,24 @@ struct args_size
HOST_WIDE_INT constant; HOST_WIDE_INT constant;
tree var; tree var;
}; };
/* Package up various arg related fields of struct args for
locate_and_pad_parm. */
struct locate_and_pad_arg_data
{
/* Size of this argument on the stack, rounded up for any padding it
gets. If REG_PARM_STACK_SPACE is defined, then register parms are
counted here, otherwise they aren't. */
struct args_size size;
/* Offset of this argument from beginning of stack-args. */
struct args_size offset;
/* Offset to the start of the stack slot. Different from OFFSET
if this arg pads downward. */
struct args_size slot_offset;
/* The amount that the stack pointer needs to be adjusted to
force alignment for the next argument. */
struct args_size alignment_pad;
};
#endif #endif
/* Add the value of the tree INC to the `struct args_size' TO. */ /* Add the value of the tree INC to the `struct args_size' TO. */
...@@ -119,8 +139,6 @@ do { \ ...@@ -119,8 +139,6 @@ do { \
usually pad upward, but pad short args downward on usually pad upward, but pad short args downward on
big-endian machines. */ big-endian machines. */
enum direction {none, upward, downward}; /* Value has this type. */
#ifndef FUNCTION_ARG_PADDING #ifndef FUNCTION_ARG_PADDING
#define FUNCTION_ARG_PADDING(MODE, TYPE) \ #define FUNCTION_ARG_PADDING(MODE, TYPE) \
(! BYTES_BIG_ENDIAN \ (! BYTES_BIG_ENDIAN \
...@@ -570,11 +588,9 @@ extern rtx expand_shift PARAMS ((enum tree_code, enum machine_mode, rtx, tree, ...@@ -570,11 +588,9 @@ extern rtx expand_shift PARAMS ((enum tree_code, enum machine_mode, rtx, tree,
rtx, int)); rtx, int));
extern rtx expand_divmod PARAMS ((int, enum tree_code, enum machine_mode, rtx, extern rtx expand_divmod PARAMS ((int, enum tree_code, enum machine_mode, rtx,
rtx, rtx, int)); rtx, rtx, int));
extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, tree, extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, int,
struct args_size *, tree, struct args_size *,
struct args_size *, struct locate_and_pad_arg_data *));
struct args_size *,
struct args_size *));
extern rtx expand_inline_function PARAMS ((tree, tree, rtx, int, tree, rtx)); extern rtx expand_inline_function PARAMS ((tree, tree, rtx, int, tree, rtx));
/* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary. */ /* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary. */
......
...@@ -4340,12 +4340,7 @@ assign_parms (fndecl) ...@@ -4340,12 +4340,7 @@ assign_parms (fndecl)
tree fndecl; tree fndecl;
{ {
tree parm; tree parm;
rtx entry_parm = 0;
rtx stack_parm = 0;
CUMULATIVE_ARGS args_so_far; CUMULATIVE_ARGS args_so_far;
enum machine_mode promoted_mode, passed_mode;
enum machine_mode nominal_mode, promoted_nominal_mode;
int unsignedp;
/* Total space needed so far for args on the stack, /* Total space needed so far for args on the stack,
given as a constant and a tree-expression. */ given as a constant and a tree-expression. */
struct args_size stack_args_size; struct args_size stack_args_size;
...@@ -4359,8 +4354,8 @@ assign_parms (fndecl) ...@@ -4359,8 +4354,8 @@ assign_parms (fndecl)
#ifdef SETUP_INCOMING_VARARGS #ifdef SETUP_INCOMING_VARARGS
int varargs_setup = 0; int varargs_setup = 0;
#endif #endif
int reg_parm_stack_space = 0;
rtx conversion_insns = 0; rtx conversion_insns = 0;
struct args_size alignment_pad;
/* Nonzero if function takes extra anonymous args. /* Nonzero if function takes extra anonymous args.
This means the last named arg must be on the stack This means the last named arg must be on the stack
...@@ -4407,6 +4402,14 @@ assign_parms (fndecl) ...@@ -4407,6 +4402,14 @@ assign_parms (fndecl)
max_parm_reg = LAST_VIRTUAL_REGISTER + 1; max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
parm_reg_stack_loc = (rtx *) ggc_alloc_cleared (max_parm_reg * sizeof (rtx)); parm_reg_stack_loc = (rtx *) ggc_alloc_cleared (max_parm_reg * sizeof (rtx));
#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 #ifdef INIT_CUMULATIVE_INCOMING_ARGS
INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX); INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX);
#else #else
...@@ -4419,14 +4422,19 @@ assign_parms (fndecl) ...@@ -4419,14 +4422,19 @@ assign_parms (fndecl)
for (parm = fnargs; parm; parm = TREE_CHAIN (parm)) for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
{ {
struct args_size stack_offset; rtx entry_parm;
struct args_size arg_size; rtx stack_parm;
enum machine_mode promoted_mode, passed_mode;
enum machine_mode nominal_mode, promoted_nominal_mode;
int unsignedp;
struct locate_and_pad_arg_data locate;
int passed_pointer = 0; int passed_pointer = 0;
int did_conversion = 0; int did_conversion = 0;
tree passed_type = DECL_ARG_TYPE (parm); tree passed_type = DECL_ARG_TYPE (parm);
tree nominal_type = TREE_TYPE (parm); tree nominal_type = TREE_TYPE (parm);
int pretend_named;
int last_named = 0, named_arg; int last_named = 0, named_arg;
int in_regs;
int partial = 0;
/* Set LAST_NAMED if this is last named arg before last /* Set LAST_NAMED if this is last named arg before last
anonymous args. */ anonymous args. */
...@@ -4490,7 +4498,7 @@ assign_parms (fndecl) ...@@ -4490,7 +4498,7 @@ assign_parms (fndecl)
|| TREE_ADDRESSABLE (passed_type) || TREE_ADDRESSABLE (passed_type)
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
|| FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode, || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode,
passed_type, named_arg) passed_type, named_arg)
#endif #endif
) )
{ {
...@@ -4560,27 +4568,52 @@ assign_parms (fndecl) ...@@ -4560,27 +4568,52 @@ assign_parms (fndecl)
it came in a register so that REG_PARM_STACK_SPACE isn't skipped. it came in a register so that REG_PARM_STACK_SPACE isn't skipped.
In this case, we call FUNCTION_ARG with NAMED set to 1 instead of In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
0 as it was the previous time. */ 0 as it was the previous time. */
in_regs = entry_parm != 0;
pretend_named = named_arg || PRETEND_OUTGOING_VARARGS_NAMED;
locate_and_pad_parm (promoted_mode, passed_type,
#ifdef STACK_PARMS_IN_REG_PARM_AREA #ifdef STACK_PARMS_IN_REG_PARM_AREA
1, in_regs = 1;
#else #endif
if (!in_regs && !named_arg)
{
int pretend_named = PRETEND_OUTGOING_VARARGS_NAMED;
if (pretend_named)
{
#ifdef FUNCTION_INCOMING_ARG #ifdef FUNCTION_INCOMING_ARG
FUNCTION_INCOMING_ARG (args_so_far, promoted_mode, in_regs = FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
passed_type, passed_type,
pretend_named) != 0, pretend_named) != 0;
#else #else
FUNCTION_ARG (args_so_far, promoted_mode, in_regs = FUNCTION_ARG (args_so_far, promoted_mode,
passed_type, passed_type,
pretend_named) != 0, pretend_named) != 0;
#endif #endif
}
}
/* If this parameter was passed both in registers and in the stack,
use the copy on the stack. */
if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
entry_parm = 0;
#ifdef FUNCTION_ARG_PARTIAL_NREGS
if (entry_parm)
partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
passed_type, named_arg);
#endif #endif
fndecl, &stack_args_size, &stack_offset, &arg_size,
&alignment_pad); memset (&locate, 0, sizeof (locate));
locate_and_pad_parm (promoted_mode, passed_type, in_regs,
entry_parm ? partial : 0, fndecl,
&stack_args_size, &locate);
{ {
rtx offset_rtx = ARGS_SIZE_RTX (stack_offset); rtx offset_rtx;
/* If we're passing this arg using a reg, make its stack home
the aligned stack slot. */
if (entry_parm)
offset_rtx = ARGS_SIZE_RTX (locate.slot_offset);
else
offset_rtx = ARGS_SIZE_RTX (locate.offset);
if (offset_rtx == const0_rtx) if (offset_rtx == const0_rtx)
stack_parm = gen_rtx_MEM (promoted_mode, internal_arg_pointer); stack_parm = gen_rtx_MEM (promoted_mode, internal_arg_pointer);
...@@ -4597,12 +4630,6 @@ assign_parms (fndecl) ...@@ -4597,12 +4630,6 @@ assign_parms (fndecl)
set_reg_attrs_for_parm (entry_parm, stack_parm); set_reg_attrs_for_parm (entry_parm, stack_parm);
} }
/* If this parameter was passed both in registers and in the stack,
use the copy on the stack. */
if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
entry_parm = 0;
#ifdef FUNCTION_ARG_PARTIAL_NREGS
/* If this parm was passed part in regs and part in memory, /* If this parm was passed part in regs and part in memory,
pretend it arrived entirely in memory pretend it arrived entirely in memory
by pushing the register-part onto the stack. by pushing the register-part onto the stack.
...@@ -4611,39 +4638,31 @@ assign_parms (fndecl) ...@@ -4611,39 +4638,31 @@ assign_parms (fndecl)
we could put it together in a pseudoreg directly, we could put it together in a pseudoreg directly,
but for now that's not worth bothering with. */ but for now that's not worth bothering with. */
if (entry_parm) if (partial)
{ {
int nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode, #ifndef MAYBE_REG_PARM_STACK_SPACE
passed_type, named_arg); /* When REG_PARM_STACK_SPACE is nonzero, stack space for
split parameters was allocated by our caller, so we
if (nregs > 0) won't be pushing it in the prolog. */
{ if (reg_parm_stack_space)
#if defined (REG_PARM_STACK_SPACE) && !defined (MAYBE_REG_PARM_STACK_SPACE)
/* When REG_PARM_STACK_SPACE is nonzero, stack space for
split parameters was allocated by our caller, so we
won't be pushing it in the prolog. */
if (REG_PARM_STACK_SPACE (fndecl) == 0)
#endif #endif
current_function_pretend_args_size current_function_pretend_args_size
= (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1) = (((partial * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
/ (PARM_BOUNDARY / BITS_PER_UNIT) / (PARM_BOUNDARY / BITS_PER_UNIT)
* (PARM_BOUNDARY / BITS_PER_UNIT)); * (PARM_BOUNDARY / BITS_PER_UNIT));
/* Handle calls that pass values in multiple non-contiguous /* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */ locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (entry_parm) == PARALLEL) if (GET_CODE (entry_parm) == PARALLEL)
emit_group_store (validize_mem (stack_parm), entry_parm, emit_group_store (validize_mem (stack_parm), entry_parm,
int_size_in_bytes (TREE_TYPE (parm))); int_size_in_bytes (TREE_TYPE (parm)));
else else
move_block_from_reg (REGNO (entry_parm), move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm),
validize_mem (stack_parm), nregs, partial, int_size_in_bytes (TREE_TYPE (parm)));
int_size_in_bytes (TREE_TYPE (parm)));
entry_parm = stack_parm; entry_parm = stack_parm;
}
} }
#endif
/* If we didn't decide this parm came in a register, /* If we didn't decide this parm came in a register,
by default it came on the stack. */ by default it came on the stack. */
...@@ -4674,9 +4693,9 @@ assign_parms (fndecl) ...@@ -4674,9 +4693,9 @@ assign_parms (fndecl)
#endif #endif
) )
{ {
stack_args_size.constant += arg_size.constant; stack_args_size.constant += locate.size.constant;
if (arg_size.var) if (locate.size.var)
ADD_PARM_SIZE (stack_args_size, arg_size.var); ADD_PARM_SIZE (stack_args_size, locate.size.var);
} }
else else
/* No stack slot was pushed for this parm. */ /* No stack slot was pushed for this parm. */
...@@ -4700,7 +4719,7 @@ assign_parms (fndecl) ...@@ -4700,7 +4719,7 @@ assign_parms (fndecl)
/* If parm was passed in memory, and we need to convert it on entry, /* If parm was passed in memory, and we need to convert it on entry,
don't store it back in that same slot. */ don't store it back in that same slot. */
if (entry_parm != 0 if (entry_parm == stack_parm
&& nominal_mode != BLKmode && nominal_mode != passed_mode) && nominal_mode != BLKmode && nominal_mode != passed_mode)
stack_parm = 0; stack_parm = 0;
...@@ -5023,7 +5042,7 @@ assign_parms (fndecl) ...@@ -5023,7 +5042,7 @@ assign_parms (fndecl)
&& ! did_conversion && ! did_conversion
&& stack_parm != 0 && stack_parm != 0
&& GET_CODE (stack_parm) == MEM && GET_CODE (stack_parm) == MEM
&& stack_offset.var == 0 && locate.offset.var == 0
&& reg_mentioned_p (virtual_incoming_args_rtx, && reg_mentioned_p (virtual_incoming_args_rtx,
XEXP (stack_parm, 0))) XEXP (stack_parm, 0)))
{ {
...@@ -5109,7 +5128,8 @@ assign_parms (fndecl) ...@@ -5109,7 +5128,8 @@ assign_parms (fndecl)
{ {
stack_parm stack_parm
= assign_stack_local (GET_MODE (entry_parm), = assign_stack_local (GET_MODE (entry_parm),
GET_MODE_SIZE (GET_MODE (entry_parm)), 0); GET_MODE_SIZE (GET_MODE (entry_parm)),
0);
set_mem_attributes (stack_parm, parm, 1); set_mem_attributes (stack_parm, parm, 1);
} }
...@@ -5280,8 +5300,11 @@ promoted_input_arg (regno, pmode, punsignedp) ...@@ -5280,8 +5300,11 @@ promoted_input_arg (regno, pmode, punsignedp)
INITIAL_OFFSET_PTR points to the current offset into the stacked INITIAL_OFFSET_PTR points to the current offset into the stacked
arguments. arguments.
The starting offset and size for this parm are returned in *OFFSET_PTR The starting offset and size for this parm are returned in
and *ARG_SIZE_PTR, respectively. LOCATE->OFFSET and LOCATE->SIZE, respectively. When IN_REGS is
nonzero, the offset is that of stack slot, which is returned in
LOCATE->SLOT_OFFSET. LOCATE->ALIGNMENT_PAD is the amount of
padding required from the initial offset ptr to the stack slot.
IN_REGS is nonzero if the argument will be passed in registers. It will IN_REGS is nonzero if the argument will be passed in registers. It will
never be set if REG_PARM_STACK_SPACE is not defined. never be set if REG_PARM_STACK_SPACE is not defined.
...@@ -5298,45 +5321,39 @@ promoted_input_arg (regno, pmode, punsignedp) ...@@ -5298,45 +5321,39 @@ promoted_input_arg (regno, pmode, punsignedp)
initial offset is not affected by this rounding, while the size always initial offset is not affected by this rounding, while the size always
is and the starting offset may be. */ is and the starting offset may be. */
/* offset_ptr will be negative for ARGS_GROW_DOWNWARD case; /* LOCATE->OFFSET will be negative for ARGS_GROW_DOWNWARD case;
initial_offset_ptr is positive because locate_and_pad_parm's INITIAL_OFFSET_PTR is positive because locate_and_pad_parm's
callers pass in the total size of args so far as callers pass in the total size of args so far as
initial_offset_ptr. arg_size_ptr is always positive. */ INITIAL_OFFSET_PTR. LOCATE->SIZE is always positive. */
void void
locate_and_pad_parm (passed_mode, type, in_regs, fndecl, locate_and_pad_parm (passed_mode, type, in_regs, partial, fndecl,
initial_offset_ptr, offset_ptr, arg_size_ptr, initial_offset_ptr, locate)
alignment_pad)
enum machine_mode passed_mode; enum machine_mode passed_mode;
tree type; tree type;
int in_regs ATTRIBUTE_UNUSED; int in_regs;
int partial;
tree fndecl ATTRIBUTE_UNUSED; tree fndecl ATTRIBUTE_UNUSED;
struct args_size *initial_offset_ptr; struct args_size *initial_offset_ptr;
struct args_size *offset_ptr; struct locate_and_pad_arg_data *locate;
struct args_size *arg_size_ptr;
struct args_size *alignment_pad;
{ {
tree sizetree tree sizetree;
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode)); enum direction where_pad;
enum direction where_pad = FUNCTION_ARG_PADDING (passed_mode, type); int boundary;
int boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type); int reg_parm_stack_space = 0;
#ifdef ARGS_GROW_DOWNWARD int part_size_in_regs;
tree s2 = sizetree;
#endif
#ifdef REG_PARM_STACK_SPACE #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 /* If we have found a stack parm before we reach the end of the
area reserved for registers, skip that area. */ area reserved for registers, skip that area. */
if (! in_regs) if (! in_regs)
{ {
int reg_parm_stack_space = 0;
#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 (reg_parm_stack_space > 0) if (reg_parm_stack_space > 0)
{ {
if (initial_offset_ptr->var) if (initial_offset_ptr->var)
...@@ -5352,54 +5369,56 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl, ...@@ -5352,54 +5369,56 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
} }
#endif /* REG_PARM_STACK_SPACE */ #endif /* REG_PARM_STACK_SPACE */
arg_size_ptr->var = 0; part_size_in_regs = 0;
arg_size_ptr->constant = 0; if (reg_parm_stack_space == 0)
alignment_pad->var = 0; part_size_in_regs = ((partial * UNITS_PER_WORD)
alignment_pad->constant = 0; / (PARM_BOUNDARY / BITS_PER_UNIT)
* (PARM_BOUNDARY / BITS_PER_UNIT));
sizetree
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
#ifdef ARGS_GROW_DOWNWARD #ifdef ARGS_GROW_DOWNWARD
locate->slot_offset.constant = -initial_offset_ptr->constant;
if (initial_offset_ptr->var) if (initial_offset_ptr->var)
{ locate->slot_offset.var = size_binop (MINUS_EXPR, ssize_int (0),
offset_ptr->constant = 0; initial_offset_ptr->var);
offset_ptr->var = size_binop (MINUS_EXPR, ssize_int (0),
initial_offset_ptr->var);
}
else
{
offset_ptr->constant = -initial_offset_ptr->constant;
offset_ptr->var = 0;
}
if (where_pad != none {
&& (!host_integerp (sizetree, 1) tree s2 = sizetree;
|| (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY)) if (where_pad != none
s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT); && (!host_integerp (sizetree, 1)
SUB_PARM_SIZE (*offset_ptr, s2); || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
SUB_PARM_SIZE (locate->slot_offset, s2);
}
locate->slot_offset.constant += part_size_in_regs;
if (!in_regs if (!in_regs
#ifdef REG_PARM_STACK_SPACE #ifdef REG_PARM_STACK_SPACE
|| REG_PARM_STACK_SPACE (fndecl) > 0 || REG_PARM_STACK_SPACE (fndecl) > 0
#endif #endif
) )
pad_to_arg_alignment (offset_ptr, boundary, alignment_pad); pad_to_arg_alignment (&locate->slot_offset, boundary,
&locate->alignment_pad);
locate->size.constant = (-initial_offset_ptr->constant
- locate->slot_offset.constant);
if (initial_offset_ptr->var) if (initial_offset_ptr->var)
arg_size_ptr->var = size_binop (MINUS_EXPR, locate->size.var = size_binop (MINUS_EXPR,
size_binop (MINUS_EXPR, size_binop (MINUS_EXPR,
ssize_int (0), ssize_int (0),
initial_offset_ptr->var), initial_offset_ptr->var),
offset_ptr->var); locate->slot_offset.var);
else /* Pad_below needs the pre-rounded size to know how much to pad
arg_size_ptr->constant = (-initial_offset_ptr->constant below. */
- offset_ptr->constant); locate->offset = locate->slot_offset;
if (where_pad == downward)
/* Pad_below needs the pre-rounded size to know how much to pad below. pad_below (&locate->offset, passed_mode, sizetree);
We only pad parameters which are not in registers as they have their
padding done elsewhere. */
if (where_pad == downward
&& !in_regs)
pad_below (offset_ptr, passed_mode, sizetree);
#else /* !ARGS_GROW_DOWNWARD */ #else /* !ARGS_GROW_DOWNWARD */
if (!in_regs if (!in_regs
...@@ -5407,8 +5426,9 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl, ...@@ -5407,8 +5426,9 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
|| REG_PARM_STACK_SPACE (fndecl) > 0 || REG_PARM_STACK_SPACE (fndecl) > 0
#endif #endif
) )
pad_to_arg_alignment (initial_offset_ptr, boundary, alignment_pad); pad_to_arg_alignment (initial_offset_ptr, boundary,
*offset_ptr = *initial_offset_ptr; &locate->alignment_pad);
locate->slot_offset = *initial_offset_ptr;
#ifdef PUSH_ROUNDING #ifdef PUSH_ROUNDING
if (passed_mode != BLKmode) if (passed_mode != BLKmode)
...@@ -5417,18 +5437,18 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl, ...@@ -5417,18 +5437,18 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
/* Pad_below needs the pre-rounded size to know how much to pad below /* Pad_below needs the pre-rounded size to know how much to pad below
so this must be done before rounding up. */ so this must be done before rounding up. */
if (where_pad == downward locate->offset = locate->slot_offset;
/* However, BLKmode args passed in regs have their padding done elsewhere. if (where_pad == downward)
The stack slot must be able to hold the entire register. */ pad_below (&locate->offset, passed_mode, sizetree);
&& !(in_regs && passed_mode == BLKmode))
pad_below (offset_ptr, passed_mode, sizetree);
if (where_pad != none if (where_pad != none
&& (!host_integerp (sizetree, 1) && (!host_integerp (sizetree, 1)
|| (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY)) || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT); sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
ADD_PARM_SIZE (*arg_size_ptr, sizetree); ADD_PARM_SIZE (locate->size, sizetree);
locate->size.constant -= part_size_in_regs;
#endif /* ARGS_GROW_DOWNWARD */ #endif /* ARGS_GROW_DOWNWARD */
} }
...@@ -5467,7 +5487,8 @@ pad_to_arg_alignment (offset_ptr, boundary, alignment_pad) ...@@ -5467,7 +5487,8 @@ pad_to_arg_alignment (offset_ptr, boundary, alignment_pad)
#endif #endif
(ARGS_SIZE_TREE (*offset_ptr), (ARGS_SIZE_TREE (*offset_ptr),
boundary / BITS_PER_UNIT); boundary / BITS_PER_UNIT);
offset_ptr->constant = 0; /*?*/ /* ARGS_SIZE_TREE includes constant term. */
offset_ptr->constant = 0;
if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY) if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var, alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var,
save_var); save_var);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment