From 9d855d2f185260d401c9a6e4631c3a59d0848f37 Mon Sep 17 00:00:00 2001 From: clm Date: Fri, 29 Oct 1999 15:23:41 +0000 Subject: [PATCH] * 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 --- gcc/ChangeLog | 13 +++++++++++++ gcc/calls.c | 27 +++++++++++++++++++-------- gcc/expr.c | 9 +++++++-- gcc/expr.h | 4 ++-- gcc/function.c | 35 +++++++++++++++++++++++++++++------ 5 files changed, 70 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3680ac3..68090e2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +Fri Oct 29 08:03:57 1999 Catherine Moore + + * 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 * except.c (free_eh_nesting_info): Free the info itself. diff --git a/gcc/calls.c b/gcc/calls.c index 3b4b1b2..b17d197 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 e509ca4..3655960 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 667ba02..816b86d 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 d5cdc26..847dcdf 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; } } -- 2.7.4