summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclm <clm@138bc75d-0d04-0410-961f-82ee72b054a4>1999-10-29 15:23:41 +0000
committerclm <clm@138bc75d-0d04-0410-961f-82ee72b054a4>1999-10-29 15:23:41 +0000
commit9d855d2f185260d401c9a6e4631c3a59d0848f37 (patch)
tree2c9f9156ff6a888e6ebe7a498f91f18465ee6e1a
parent0388e90f0664ab4bcd63ffb134d0fa3da1ee7da5 (diff)
downloadgcc-9d855d2f185260d401c9a6e4631c3a59d0848f37.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30257 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/calls.c27
-rw-r--r--gcc/expr.c9
-rw-r--r--gcc/expr.h4
-rw-r--r--gcc/function.c35
5 files changed, 70 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3680ac3bf0b..68090e2a931 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+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>
* except.c (free_eh_nesting_info): Free the info itself.
diff --git a/gcc/calls.c b/gcc/calls.c
index 3b4b1b20921..b17d1971fdf 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -106,6 +106,9 @@ struct arg_data
word-sized pseudos we made. */
rtx *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
@@ -898,6 +901,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
/* Count arg position in order args appear. */
int argpos;
+ struct args_size alignment_pad;
int i;
tree p;
@@ -1093,12 +1097,14 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
args[i].reg != 0,
#endif
fndecl, args_size, &args[i].offset,
- &args[i].size);
+ &args[i].size, &alignment_pad);
#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)
@@ -2688,7 +2694,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
locate_and_pad_parm (mode, NULL_TREE,
argvec[count].reg && argvec[count].partial == 0,
NULL_TREE, &args_size, &argvec[count].offset,
- &argvec[count].size);
+ &argvec[count].size, &alignment_pad);
if (argvec[count].size.var)
abort ();
@@ -2917,7 +2923,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
#endif
emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
argblock, GEN_INT (argvec[argnum].offset.constant),
- reg_parm_stack_space);
+ reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
#ifdef ACCUMULATE_OUTGOING_ARGS
/* Now mark the segment we just used. */
@@ -3072,6 +3078,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
rtx fun;
int inc;
int count;
+ struct args_size alignment_pad;
rtx argblock = 0;
CUMULATIVE_ARGS args_so_far;
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,
locate_and_pad_parm (Pmode, NULL_TREE,
argvec[count].reg && argvec[count].partial == 0,
NULL_TREE, &args_size, &argvec[count].offset,
- &argvec[count].size);
+ &argvec[count].size, &alignment_pad);
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,
locate_and_pad_parm (mode, NULL_TREE,
argvec[count].reg && argvec[count].partial == 0,
NULL_TREE, &args_size, &argvec[count].offset,
- &argvec[count].size);
+ &argvec[count].size, &alignment_pad);
if (argvec[count].size.var)
abort ();
@@ -3486,7 +3493,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
#endif
emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
argblock, GEN_INT (argvec[argnum].offset.constant),
- reg_parm_stack_space);
+ reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
#ifdef ACCUMULATE_OUTGOING_ARGS
/* Now mark the segment we just used. */
@@ -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;
stack_usage_map = initial_stack_usage_map;
#endif
+ struct args_size alignment_pad;
return value;
}
@@ -3899,7 +3907,9 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
This can either be done with push or copy insns. */
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, 0,
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
{
@@ -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,
TYPE_ALIGN (TREE_TYPE (pval)) / BITS_PER_UNIT, partial,
reg, excess, argblock, ARGS_SIZE_RTX (arg->offset),
- reg_parm_stack_space);
+ reg_parm_stack_space,
+ ARGS_SIZE_RTX (arg->alignment_pad));
}
diff --git a/gcc/expr.c b/gcc/expr.c
index e509ca44073..36559608720 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2870,7 +2870,8 @@ get_push_address (size)
void
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;
enum machine_mode mode;
tree type;
@@ -2882,6 +2883,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
rtx args_addr;
rtx args_so_far;
int reg_parm_stack_space;
+ rtx alignment_pad;
{
rtx xinner;
enum direction stack_direction
@@ -3176,7 +3178,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
0, args_addr,
GEN_INT (args_offset + ((i - not_stack + skip)
* UNITS_PER_WORD)),
- reg_parm_stack_space);
+ reg_parm_stack_space, alignment_pad);
}
else
{
@@ -3248,6 +3250,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
if (extra && args_addr == 0 && where_pad == stack_direction)
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.
diff --git a/gcc/expr.h b/gcc/expr.h
index 667ba0284d0..816b86dcef5 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -983,7 +983,7 @@ extern rtx gen_push_operand PROTO((void));
#ifdef TREE_CODE
/* 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,
- int, rtx, int, rtx, rtx, int));
+ int, rtx, int, rtx, rtx, int, rtx));
/* Emit library call. */
extern void emit_library_call PVPROTO((rtx orgfun, int no_queue,
@@ -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_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));
/* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary. */
extern rtx label_rtx PROTO((tree));
diff --git a/gcc/function.c b/gcc/function.c
index d5cdc2610cc..847dcdf0f87 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -252,7 +252,7 @@ static void instantiate_decls_1 PROTO((tree, int));
static void instantiate_decl PROTO((rtx, int, int));
static int instantiate_virtual_regs_1 PROTO((rtx *, rtx, int));
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
static void pad_below PROTO((struct args_size *, enum machine_mode,
tree));
@@ -3957,6 +3957,7 @@ assign_parms (fndecl)
int varargs_setup = 0;
#endif
rtx conversion_insns = 0;
+ struct args_size alignment_pad;
/* Nonzero if the last arg is named `__builtin_va_alist',
which is used on some machines for old-fashioned non-ANSI varargs.h;
@@ -4169,7 +4170,8 @@ assign_parms (fndecl)
pretend_named) != 0,
#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);
@@ -4861,7 +4863,8 @@ promoted_input_arg (regno, pmode, punsignedp)
void
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;
tree type;
int in_regs;
@@ -4869,6 +4872,8 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
struct args_size *initial_offset_ptr;
struct args_size *offset_ptr;
struct args_size *arg_size_ptr;
+ struct args_size *alignment_pad;
+
{
tree sizetree
= 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,
sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
SUB_PARM_SIZE (*offset_ptr, sizetree);
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)
{
arg_size_ptr->var = size_binop (MINUS_EXPR,
@@ -4938,7 +4943,7 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
- offset_ptr->constant);
}
#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;
#ifdef PUSH_ROUNDING
@@ -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. */
static void
-pad_to_arg_alignment (offset_ptr, boundary)
+pad_to_arg_alignment (offset_ptr, boundary, alignment_pad)
struct args_size *offset_ptr;
int boundary;
+ struct args_size *alignment_pad;
{
+ tree save_var;
+ HOST_WIDE_INT save_constant;
+
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 (offset_ptr->var)
@@ -4986,6 +5005,8 @@ pad_to_arg_alignment (offset_ptr, boundary)
(ARGS_SIZE_TREE (*offset_ptr),
boundary / BITS_PER_UNIT);
offset_ptr->constant = 0; /*?*/
+ if (boundary > PARM_BOUNDARY)
+ alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var, save_var);
}
else
offset_ptr->constant =
@@ -4994,6 +5015,8 @@ pad_to_arg_alignment (offset_ptr, boundary)
#else
CEIL_ROUND (offset_ptr->constant, boundary_in_bytes);
#endif
+ if (boundary > PARM_BOUNDARY)
+ alignment_pad->constant = offset_ptr->constant - save_constant;
}
}