aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorJohn David Anglin <dave@hiauly1.hia.nrc.ca>2002-09-17 03:30:37 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2002-09-17 03:30:37 +0000
commit9dff28ab5386ec651699c6245823e3e2c68d1c64 (patch)
tree9562fab54c7f71944f468dd8ea88012248c2545e /gcc/function.c
parent94313f351a9d53ae192d425c82b023b895827009 (diff)
downloadgcc-9dff28ab5386ec651699c6245823e3e2c68d1c64.zip
gcc-9dff28ab5386ec651699c6245823e3e2c68d1c64.tar.gz
gcc-9dff28ab5386ec651699c6245823e3e2c68d1c64.tar.bz2
calls.c (store_one_arg): Set default alignment for BLKmode arguments to BITS_PER_UNIT when...
* calls.c (store_one_arg): Set default alignment for BLKmode arguments to BITS_PER_UNIT when ARGS_GROW_DOWNWARD and the padding direction is downward. * function.c (pad_below): Always compile. (locate_and_pad_parm): If defined ARGS_GROW_DOWNWARD, pad argument to alignment when it is not in a register or REG_PARM_STACK_SPACE is true. Pad below when the argument is not in a register and the padding direction is downward. * pa-64.h (MUST_PASS_IN_STACK): Move define to pa.h. (PAD_VARARGS_DOWN): Define. * pa.c (function_arg_padding): Revise padding directions to make them compatible with the 32 and 64-bit runtime architecture documentation. (hppa_va_arg): Add code to handle variable and size zero arguments passed by reference on TARGET_64BIT. Reformat. (function_arg): Use a PARALLEL for BLKmode and aggregates args on TARGET_64BIT. Use a DImode PARALLEL for BLKmode args 5 to 8 bytes wide when !TARGET_64BIT. Move forward check for mode==VOIDmode. Add comments. * pa.h (MAX_PARM_BOUNDARY): Correct define for TARGET_64BIT. (RETURN_IN_MEMORY): Return size zero types in memory. (FUNCTION_VALUE): Return TFmode in general registers. (MUST_PASS_IN_STACK): Define. (FUNCTION_ARG_BOUNDARY): Simplify. (FUNCTION_ARG_PASS_BY_REFERENCE): Pass variable and zero sized types by reference. (FUNCTION_ARG_CALLEE_COPIES): Define to FUNCTION_ARG_PASS_BY_REFERENCE. From-SVN: r57226
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 424f06c..edc1581 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -255,10 +255,8 @@ static int instantiate_virtual_regs_1 PARAMS ((rtx *, rtx, int));
static void delete_handlers PARAMS ((void));
static void pad_to_arg_alignment PARAMS ((struct args_size *, int,
struct args_size *));
-#ifndef ARGS_GROW_DOWNWARD
static void pad_below PARAMS ((struct args_size *, enum machine_mode,
tree));
-#endif
static rtx round_trampoline_addr PARAMS ((rtx));
static rtx adjust_trampoline_addr PARAMS ((rtx));
static tree *identify_blocks_1 PARAMS ((rtx, tree *, tree *, tree *));
@@ -5244,6 +5242,9 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
enum direction where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
int boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
+#ifdef ARGS_GROW_DOWNWARD
+ tree s2 = sizetree;
+#endif
#ifdef REG_PARM_STACK_SPACE
/* If we have found a stack parm before we reach the end of the
@@ -5289,13 +5290,20 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
offset_ptr->constant = -initial_offset_ptr->constant;
offset_ptr->var = 0;
}
+
if (where_pad != none
&& (!host_integerp (sizetree, 1)
|| (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
- sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
- SUB_PARM_SIZE (*offset_ptr, sizetree);
- if (where_pad != downward)
+ s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
+ SUB_PARM_SIZE (*offset_ptr, s2);
+
+ if (!in_regs
+#ifdef REG_PARM_STACK_SPACE
+ || REG_PARM_STACK_SPACE (fndecl) > 0
+#endif
+ )
pad_to_arg_alignment (offset_ptr, boundary, alignment_pad);
+
if (initial_offset_ptr->var)
arg_size_ptr->var = size_binop (MINUS_EXPR,
size_binop (MINUS_EXPR,
@@ -5307,6 +5315,13 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
arg_size_ptr->constant = (-initial_offset_ptr->constant
- offset_ptr->constant);
+ /* Pad_below needs the pre-rounded size to know how much to pad below.
+ 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 */
if (!in_regs
#ifdef REG_PARM_STACK_SPACE
@@ -5392,7 +5407,6 @@ pad_to_arg_alignment (offset_ptr, boundary, alignment_pad)
}
}
-#ifndef ARGS_GROW_DOWNWARD
static void
pad_below (offset_ptr, passed_mode, sizetree)
struct args_size *offset_ptr;
@@ -5420,7 +5434,6 @@ pad_below (offset_ptr, passed_mode, sizetree)
}
}
}
-#endif
/* Walk the tree of blocks describing the binding levels within a function
and warn about uninitialized variables.