From 5f4cd67005584e138e0b4bcb4cc9769cb8faba64 Mon Sep 17 00:00:00 2001 From: amodra Date: Mon, 14 Jul 2003 05:17:18 +0000 Subject: * doc/tm.texi (BLOCK_REG_PADDING): Describe. * expr.h (struct locate_and_pad_arg_data): Add where_pad. (emit_group_load, emit_group_store): Adjust declarations. Remove most occurrences of #ifdef TREE_CODE. * expr.c (emit_group_load): Add "type" param, and use BLOCK_REG_PADDING to determine need for a shift. Optimize non- aligned accesses if !SLOW_UNALIGNED_ACCESS. (emit_group_store): Likewise. (emit_push_insn, expand_assignment, store_expr, expand_expr): Adjust emit_group_load and emit_group_store calls. * calls.c (store_unaligned_arguments_into_pseudos): Tidy. Use BLOCK_REG_PADDING to determine whether we need endian_correction. (load_register_parameters): Localize vars. Handle shifting of small values to the correct end of regs. Adjust emit_group_load call. (expand_call, emit_library_call_value_1): Adjust emit_group_load and emit_group_store calls. * function.c (assign_parms): Set mem alignment for stack slots. Adjust emit_group_store call. Store values at the "wrong" end of regs to the stack. Use BLOCK_REG_PADDING. (locate_and_pad_parm): Save where_pad. (expand_function_end): Adjust emit_group_load call. * stmt.c (expand_value_return): Adjust emit_group_load call. * Makefile.in (calls.o): Depend on $(OPTABS_H). * config/rs6000/linux64.h (TARGET_LITTLE_ENDIAN): Redefine as 0. (AGGREGATE_PADDING_FIXED, AGGREGATES_PAD_UPWARD_ALWAYS): Define. (MUST_PASS_IN_STACK): Define. (BLOCK_REG_PADDING): Define. * config/rs6000/rs6000.h (struct rs6000_args): Remove orig_nargs. (PAD_VARARGS_DOWN): Define in terms of FUNCTION_ARG_PADDING. * config/rs6000/rs6000.c (init_cumulative_args): Don't set orig_nargs. (function_arg_padding): !AGGREGATE_PADDING_FIXED compatibility code. Act on AGGREGATES_PAD_UPWARD_ALWAYS. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69318 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/function.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'gcc/function.c') diff --git a/gcc/function.c b/gcc/function.c index 301d59d498d..c3f4dc604d4 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -4507,6 +4507,8 @@ assign_parms (tree fndecl) offset_rtx)); set_mem_attributes (stack_parm, parm, 1); + if (entry_parm && MEM_ATTRS (stack_parm)->align < PARM_BOUNDARY) + set_mem_align (stack_parm, PARM_BOUNDARY); /* Set also REG_ATTRS if parameter was passed in a register. */ if (entry_parm) @@ -4538,6 +4540,7 @@ assign_parms (tree fndecl) locations. The Irix 6 ABI has examples of this. */ if (GET_CODE (entry_parm) == PARALLEL) emit_group_store (validize_mem (stack_parm), entry_parm, + TREE_TYPE (parm), int_size_in_bytes (TREE_TYPE (parm))); else @@ -4644,7 +4647,12 @@ assign_parms (tree fndecl) Set DECL_RTL to that place. */ - if (nominal_mode == BLKmode || GET_CODE (entry_parm) == PARALLEL) + if (nominal_mode == BLKmode +#ifdef BLOCK_REG_PADDING + || (locate.where_pad == (BYTES_BIG_ENDIAN ? upward : downward) + && GET_MODE_SIZE (promoted_mode) < UNITS_PER_WORD) +#endif + || GET_CODE (entry_parm) == PARALLEL) { /* If a BLKmode arrives in registers, copy it to a stack slot. Handle calls that pass values in multiple non-contiguous @@ -4680,7 +4688,7 @@ assign_parms (tree fndecl) /* Handle calls that pass values in multiple non-contiguous locations. The Irix 6 ABI has examples of this. */ if (GET_CODE (entry_parm) == PARALLEL) - emit_group_store (mem, entry_parm, size); + emit_group_store (mem, entry_parm, TREE_TYPE (parm), size); else if (size == 0) ; @@ -4692,7 +4700,13 @@ assign_parms (tree fndecl) enum machine_mode mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0); - if (mode != BLKmode) + if (mode != BLKmode +#ifdef BLOCK_REG_PADDING + && (size == UNITS_PER_WORD + || (BLOCK_REG_PADDING (mode, TREE_TYPE (parm), 1) + != (BYTES_BIG_ENDIAN ? upward : downward))) +#endif + ) { rtx reg = gen_rtx_REG (mode, REGNO (entry_parm)); emit_move_insn (change_address (mem, mode, 0), reg); @@ -4703,7 +4717,13 @@ assign_parms (tree fndecl) to memory. Note that the previous test doesn't handle all cases (e.g. SIZE == 3). */ else if (size != UNITS_PER_WORD - && BYTES_BIG_ENDIAN) +#ifdef BLOCK_REG_PADDING + && (BLOCK_REG_PADDING (mode, TREE_TYPE (parm), 1) + == downward) +#else + && BYTES_BIG_ENDIAN +#endif + ) { rtx tem, x; int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT; @@ -5367,6 +5387,7 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs, = 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); + locate->where_pad = where_pad; #ifdef ARGS_GROW_DOWNWARD locate->slot_offset.constant = -initial_offset_ptr->constant; @@ -7036,6 +7057,7 @@ expand_function_end (void) emit_group_move (real_decl_rtl, decl_rtl); else emit_group_load (real_decl_rtl, decl_rtl, + TREE_TYPE (decl_result), int_size_in_bytes (TREE_TYPE (decl_result))); } else -- cgit v1.2.1