Commit 4fc026cd by Catherine Moore Committed by Catherine Moore

expr.c (emit_push_insn): New argument alignment_pad.

        * expr.c (emit_push_insn): New argument alignment_pad.
        Update all callers.  Adjust stack pointer based on alignment pad.
        * function.c (pad_to_arg_alignment):  New argument alignment_pad.
        Update all callers.  Track alignment_pad if boundary > PARM_BOUNDARY.
        (locate_and_pad_parm): New argument alignment_pad.  Update all
        callers.
        * expr.h (emit_push_insn): Update prototype.
        (locate_and_pad_parm): Update prototype.
        * calls.c (arg_data):  Add new field alignment_pad.
        (initialize_argument_information): Initialize alignment_pad.

From-SVN: r30257
parent 5faf03ae
Fri Oct 29 08:03:57 1999 Catherine Moore <clm@cygnus.com>
* expr.c (emit_push_insn): New argument alignment_pad.
Update all callers. Adjust stack pointer based on alignment pad.
* function.c (pad_to_arg_alignment): New argument alignment_pad.
Update all callers. Track alignment_pad if boundary > PARM_BOUNDARY.
(locate_and_pad_parm): New argument alignment_pad. Update all
callers.
* expr.h (emit_push_insn): Update prototype.
(locate_and_pad_parm): Update prototype.
* calls.c (arg_data): Add new field alignment_pad.
(initialize_argument_information): Initialize alignment_pad.
Fri Oct 29 02:51:35 1999 Mark Mitchell <mark@codesourcery.com> Fri Oct 29 02:51:35 1999 Mark Mitchell <mark@codesourcery.com>
* except.c (free_eh_nesting_info): Free the info itself. * except.c (free_eh_nesting_info): Free the info itself.
......
...@@ -106,6 +106,9 @@ struct arg_data ...@@ -106,6 +106,9 @@ 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;
}; };
#ifdef ACCUMULATE_OUTGOING_ARGS #ifdef ACCUMULATE_OUTGOING_ARGS
...@@ -898,6 +901,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args, ...@@ -898,6 +901,7 @@ 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;
...@@ -1093,12 +1097,14 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args, ...@@ -1093,12 +1097,14 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
args[i].reg != 0, args[i].reg != 0,
#endif #endif
fndecl, args_size, &args[i].offset, fndecl, args_size, &args[i].offset,
&args[i].size); &args[i].size, &alignment_pad);
#ifndef ARGS_GROW_DOWNWARD #ifndef ARGS_GROW_DOWNWARD
args[i].slot_offset = *args_size; args[i].slot_offset = *args_size;
#endif #endif
args[i].alignment_pad = alignment_pad;
/* If a part of the arg was put into registers, /* If a part of the arg was put into registers,
don't include that part in the amount pushed. */ don't include that part in the amount pushed. */
if (reg_parm_stack_space == 0 && ! args[i].pass_on_stack) if (reg_parm_stack_space == 0 && ! args[i].pass_on_stack)
...@@ -2688,7 +2694,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, ...@@ -2688,7 +2694,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
locate_and_pad_parm (mode, NULL_TREE, locate_and_pad_parm (mode, NULL_TREE,
argvec[count].reg && argvec[count].partial == 0, argvec[count].reg && argvec[count].partial == 0,
NULL_TREE, &args_size, &argvec[count].offset, NULL_TREE, &args_size, &argvec[count].offset,
&argvec[count].size); &argvec[count].size, &alignment_pad);
if (argvec[count].size.var) if (argvec[count].size.var)
abort (); abort ();
...@@ -2917,7 +2923,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, ...@@ -2917,7 +2923,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
#endif #endif
emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0, emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
argblock, GEN_INT (argvec[argnum].offset.constant), argblock, GEN_INT (argvec[argnum].offset.constant),
reg_parm_stack_space); reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
#ifdef ACCUMULATE_OUTGOING_ARGS #ifdef ACCUMULATE_OUTGOING_ARGS
/* Now mark the segment we just used. */ /* Now mark the segment we just used. */
...@@ -3072,6 +3078,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, ...@@ -3072,6 +3078,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
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 { rtx value; enum machine_mode mode; rtx reg; int partial; struct arg { rtx value; enum machine_mode mode; rtx reg; int partial;
...@@ -3192,7 +3199,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, ...@@ -3192,7 +3199,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
locate_and_pad_parm (Pmode, NULL_TREE, locate_and_pad_parm (Pmode, NULL_TREE,
argvec[count].reg && argvec[count].partial == 0, argvec[count].reg && argvec[count].partial == 0,
NULL_TREE, &args_size, &argvec[count].offset, NULL_TREE, &args_size, &argvec[count].offset,
&argvec[count].size); &argvec[count].size, &alignment_pad);
if (argvec[count].reg == 0 || argvec[count].partial != 0 if (argvec[count].reg == 0 || argvec[count].partial != 0
...@@ -3258,7 +3265,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, ...@@ -3258,7 +3265,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
locate_and_pad_parm (mode, NULL_TREE, locate_and_pad_parm (mode, NULL_TREE,
argvec[count].reg && argvec[count].partial == 0, argvec[count].reg && argvec[count].partial == 0,
NULL_TREE, &args_size, &argvec[count].offset, NULL_TREE, &args_size, &argvec[count].offset,
&argvec[count].size); &argvec[count].size, &alignment_pad);
if (argvec[count].size.var) if (argvec[count].size.var)
abort (); abort ();
...@@ -3486,7 +3493,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, ...@@ -3486,7 +3493,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
#endif #endif
emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0, emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
argblock, GEN_INT (argvec[argnum].offset.constant), argblock, GEN_INT (argvec[argnum].offset.constant),
reg_parm_stack_space); reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
#ifdef ACCUMULATE_OUTGOING_ARGS #ifdef ACCUMULATE_OUTGOING_ARGS
/* Now mark the segment we just used. */ /* Now mark the segment we just used. */
...@@ -3636,6 +3643,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, ...@@ -3636,6 +3643,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
highest_outgoing_arg_in_use = initial_highest_arg_in_use; highest_outgoing_arg_in_use = initial_highest_arg_in_use;
stack_usage_map = initial_stack_usage_map; stack_usage_map = initial_stack_usage_map;
#endif #endif
struct args_size alignment_pad;
return value; return value;
} }
...@@ -3899,7 +3907,9 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, ...@@ -3899,7 +3907,9 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
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, 0, emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, 0,
partial, reg, used - size, argblock, partial, reg, used - size, argblock,
ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space); ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad));
} }
else else
{ {
...@@ -3932,7 +3942,8 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, ...@@ -3932,7 +3942,8 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx, emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
TYPE_ALIGN (TREE_TYPE (pval)) / BITS_PER_UNIT, partial, TYPE_ALIGN (TREE_TYPE (pval)) / BITS_PER_UNIT, partial,
reg, excess, argblock, ARGS_SIZE_RTX (arg->offset), reg, excess, argblock, ARGS_SIZE_RTX (arg->offset),
reg_parm_stack_space); reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad));
} }
......
...@@ -2870,7 +2870,8 @@ get_push_address (size) ...@@ -2870,7 +2870,8 @@ get_push_address (size)
void void
emit_push_insn (x, mode, type, size, align, partial, reg, extra, emit_push_insn (x, mode, type, size, align, partial, reg, extra,
args_addr, args_so_far, reg_parm_stack_space) args_addr, args_so_far, reg_parm_stack_space,
alignment_pad)
register rtx x; register rtx x;
enum machine_mode mode; enum machine_mode mode;
tree type; tree type;
...@@ -2882,6 +2883,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, ...@@ -2882,6 +2883,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
rtx args_addr; rtx args_addr;
rtx args_so_far; rtx args_so_far;
int reg_parm_stack_space; int reg_parm_stack_space;
rtx alignment_pad;
{ {
rtx xinner; rtx xinner;
enum direction stack_direction enum direction stack_direction
...@@ -3176,7 +3178,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, ...@@ -3176,7 +3178,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
0, args_addr, 0, args_addr,
GEN_INT (args_offset + ((i - not_stack + skip) GEN_INT (args_offset + ((i - not_stack + skip)
* UNITS_PER_WORD)), * UNITS_PER_WORD)),
reg_parm_stack_space); reg_parm_stack_space, alignment_pad);
} }
else else
{ {
...@@ -3248,6 +3250,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, ...@@ -3248,6 +3250,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
if (extra && args_addr == 0 && where_pad == stack_direction) if (extra && args_addr == 0 && where_pad == stack_direction)
anti_adjust_stack (GEN_INT (extra)); anti_adjust_stack (GEN_INT (extra));
if (alignment_pad)
anti_adjust_stack (alignment_pad);
} }
/* Expand an assignment that stores the value of FROM into TO. /* Expand an assignment that stores the value of FROM into TO.
......
...@@ -983,7 +983,7 @@ extern rtx gen_push_operand PROTO((void)); ...@@ -983,7 +983,7 @@ extern rtx gen_push_operand PROTO((void));
#ifdef TREE_CODE #ifdef TREE_CODE
/* Generate code to push something onto the stack, given its mode and type. */ /* Generate code to push something onto the stack, given its mode and type. */
extern void emit_push_insn PROTO((rtx, enum machine_mode, tree, rtx, int, extern void emit_push_insn PROTO((rtx, enum machine_mode, tree, rtx, int,
int, rtx, int, rtx, rtx, int)); int, rtx, int, rtx, rtx, int, rtx));
/* Emit library call. */ /* Emit library call. */
extern void emit_library_call PVPROTO((rtx orgfun, int no_queue, extern void emit_library_call PVPROTO((rtx orgfun, int no_queue,
...@@ -1075,7 +1075,7 @@ extern rtx expand_call PROTO((tree, rtx, int)); ...@@ -1075,7 +1075,7 @@ extern rtx expand_call PROTO((tree, rtx, int));
extern rtx expand_shift PROTO((enum tree_code, enum machine_mode, rtx, tree, rtx, int)); extern rtx expand_shift PROTO((enum tree_code, enum machine_mode, rtx, tree, rtx, int));
extern rtx expand_divmod PROTO((int, enum tree_code, enum machine_mode, rtx, rtx, rtx, int)); extern rtx expand_divmod PROTO((int, enum tree_code, enum machine_mode, rtx, rtx, rtx, int));
extern void locate_and_pad_parm PROTO((enum machine_mode, tree, int, tree, struct args_size *, struct args_size *, struct args_size *)); extern void locate_and_pad_parm PROTO((enum machine_mode, tree, int, tree, struct args_size *, struct args_size *, struct args_size *, struct args_size *));
extern rtx expand_inline_function PROTO((tree, tree, rtx, int, tree, rtx)); extern rtx expand_inline_function PROTO((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. */
extern rtx label_rtx PROTO((tree)); extern rtx label_rtx PROTO((tree));
......
...@@ -252,7 +252,7 @@ static void instantiate_decls_1 PROTO((tree, int)); ...@@ -252,7 +252,7 @@ static void instantiate_decls_1 PROTO((tree, int));
static void instantiate_decl PROTO((rtx, int, int)); static void instantiate_decl PROTO((rtx, int, int));
static int instantiate_virtual_regs_1 PROTO((rtx *, rtx, int)); static int instantiate_virtual_regs_1 PROTO((rtx *, rtx, int));
static void delete_handlers PROTO((void)); static void delete_handlers PROTO((void));
static void pad_to_arg_alignment PROTO((struct args_size *, int)); static void pad_to_arg_alignment PROTO((struct args_size *, int, struct args_size *));
#ifndef ARGS_GROW_DOWNWARD #ifndef ARGS_GROW_DOWNWARD
static void pad_below PROTO((struct args_size *, enum machine_mode, static void pad_below PROTO((struct args_size *, enum machine_mode,
tree)); tree));
...@@ -3957,6 +3957,7 @@ assign_parms (fndecl) ...@@ -3957,6 +3957,7 @@ assign_parms (fndecl)
int varargs_setup = 0; int varargs_setup = 0;
#endif #endif
rtx conversion_insns = 0; rtx conversion_insns = 0;
struct args_size alignment_pad;
/* Nonzero if the last arg is named `__builtin_va_alist', /* Nonzero if the last arg is named `__builtin_va_alist',
which is used on some machines for old-fashioned non-ANSI varargs.h; which is used on some machines for old-fashioned non-ANSI varargs.h;
...@@ -4169,7 +4170,8 @@ assign_parms (fndecl) ...@@ -4169,7 +4170,8 @@ assign_parms (fndecl)
pretend_named) != 0, pretend_named) != 0,
#endif #endif
#endif #endif
fndecl, &stack_args_size, &stack_offset, &arg_size); fndecl, &stack_args_size, &stack_offset, &arg_size,
&alignment_pad);
{ {
rtx offset_rtx = ARGS_SIZE_RTX (stack_offset); rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
...@@ -4861,7 +4863,8 @@ promoted_input_arg (regno, pmode, punsignedp) ...@@ -4861,7 +4863,8 @@ promoted_input_arg (regno, pmode, punsignedp)
void void
locate_and_pad_parm (passed_mode, type, in_regs, fndecl, locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
initial_offset_ptr, offset_ptr, arg_size_ptr) initial_offset_ptr, offset_ptr, arg_size_ptr,
alignment_pad)
enum machine_mode passed_mode; enum machine_mode passed_mode;
tree type; tree type;
int in_regs; int in_regs;
...@@ -4869,6 +4872,8 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl, ...@@ -4869,6 +4872,8 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
struct args_size *initial_offset_ptr; struct args_size *initial_offset_ptr;
struct args_size *offset_ptr; struct args_size *offset_ptr;
struct args_size *arg_size_ptr; 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)); = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
...@@ -4923,7 +4928,7 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl, ...@@ -4923,7 +4928,7 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT); sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
SUB_PARM_SIZE (*offset_ptr, sizetree); SUB_PARM_SIZE (*offset_ptr, sizetree);
if (where_pad != downward) if (where_pad != downward)
pad_to_arg_alignment (offset_ptr, boundary); pad_to_arg_alignment (offset_ptr, boundary, alignment_pad);
if (initial_offset_ptr->var) if (initial_offset_ptr->var)
{ {
arg_size_ptr->var = size_binop (MINUS_EXPR, arg_size_ptr->var = size_binop (MINUS_EXPR,
...@@ -4938,7 +4943,7 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl, ...@@ -4938,7 +4943,7 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
- offset_ptr->constant); - offset_ptr->constant);
} }
#else /* !ARGS_GROW_DOWNWARD */ #else /* !ARGS_GROW_DOWNWARD */
pad_to_arg_alignment (initial_offset_ptr, boundary); pad_to_arg_alignment (initial_offset_ptr, boundary, alignment_pad);
*offset_ptr = *initial_offset_ptr; *offset_ptr = *initial_offset_ptr;
#ifdef PUSH_ROUNDING #ifdef PUSH_ROUNDING
...@@ -4967,12 +4972,26 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl, ...@@ -4967,12 +4972,26 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
BOUNDARY is measured in bits, but must be a multiple of a storage unit. */ BOUNDARY is measured in bits, but must be a multiple of a storage unit. */
static void static void
pad_to_arg_alignment (offset_ptr, boundary) pad_to_arg_alignment (offset_ptr, boundary, alignment_pad)
struct args_size *offset_ptr; struct args_size *offset_ptr;
int boundary; int boundary;
struct args_size *alignment_pad;
{ {
tree save_var;
HOST_WIDE_INT save_constant;
int boundary_in_bytes = boundary / BITS_PER_UNIT; int boundary_in_bytes = boundary / BITS_PER_UNIT;
if (boundary > PARM_BOUNDARY)
{
save_var = offset_ptr->var;
save_constant = offset_ptr->constant;
}
alignment_pad->var = NULL_TREE;
alignment_pad->constant = 0;
/* END CYGNUS LOCAL */
if (boundary > BITS_PER_UNIT) if (boundary > BITS_PER_UNIT)
{ {
if (offset_ptr->var) if (offset_ptr->var)
...@@ -4986,6 +5005,8 @@ pad_to_arg_alignment (offset_ptr, boundary) ...@@ -4986,6 +5005,8 @@ pad_to_arg_alignment (offset_ptr, boundary)
(ARGS_SIZE_TREE (*offset_ptr), (ARGS_SIZE_TREE (*offset_ptr),
boundary / BITS_PER_UNIT); boundary / BITS_PER_UNIT);
offset_ptr->constant = 0; /*?*/ offset_ptr->constant = 0; /*?*/
if (boundary > PARM_BOUNDARY)
alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var, save_var);
} }
else else
offset_ptr->constant = offset_ptr->constant =
...@@ -4994,6 +5015,8 @@ pad_to_arg_alignment (offset_ptr, boundary) ...@@ -4994,6 +5015,8 @@ pad_to_arg_alignment (offset_ptr, boundary)
#else #else
CEIL_ROUND (offset_ptr->constant, boundary_in_bytes); CEIL_ROUND (offset_ptr->constant, boundary_in_bytes);
#endif #endif
if (boundary > PARM_BOUNDARY)
alignment_pad->constant = offset_ptr->constant - save_constant;
} }
} }
......
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