aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoern Rennecke <amylaar@gcc.gnu.org>2004-06-29 18:37:13 +0100
committerJoern Rennecke <amylaar@gcc.gnu.org>2004-06-29 18:37:13 +0100
commit4961683533a0f3dd4ecd4aef5d2084463be1e582 (patch)
treeb8d2fd39f7ce05496aa22639862e39f75ff480aa /gcc
parent8d2fb08dbf478c912b8e098606e18848741ba2a2 (diff)
downloadgcc-4961683533a0f3dd4ecd4aef5d2084463be1e582.zip
gcc-4961683533a0f3dd4ecd4aef5d2084463be1e582.tar.gz
gcc-4961683533a0f3dd4ecd4aef5d2084463be1e582.tar.bz2
Fix gcc.dg/builtin-apply2.c failures:
* sh.h (TARGET_VARARGS_PRETEND_ARGS): Define. * sh.c (extra_push): Delete. (sh_expand_prologue): Don't do extra stack adjustment for current_function_pretend_args_size if it comes from varargs setup. Use TARGET_VARARGS_PRETEND_ARGS. Don't set extra_push. (sh_expand_epilogue): Don't use extra_push. (sh_setup_incoming_varargs): Set pretend_arg_size when necessary. From-SVN: r83864
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/sh/sh.c39
-rw-r--r--gcc/config/sh/sh.h5
2 files changed, 30 insertions, 14 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 2308f1b..3f5889d 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -4700,8 +4700,6 @@ output_jump_label_table (void)
/* Number of bytes pushed for anonymous args, used to pass information
between expand_prologue and expand_epilogue. */
-static int extra_push;
-
/* Adjust the stack by SIZE bytes. REG holds the rtl of the register to be
adjusted. If epilogue_p is zero, this is for a prologue; otherwise, it's
for an epilogue and a negative value means that it's for a sibcall
@@ -5321,17 +5319,21 @@ sh_expand_prologue (void)
int d, i;
int d_rounding = 0;
int save_flags = target_flags;
+ int pretend_args;
current_function_interrupt = sh_cfun_interrupt_handler_p ();
/* We have pretend args if we had an object sent partially in registers
and partially on the stack, e.g. a large structure. */
- output_stack_adjust (-current_function_pretend_args_size
+ pretend_args = current_function_pretend_args_size;
+ if (TARGET_VARARGS_PRETEND_ARGS (current_function_decl)
+ && (NPARM_REGS(SImode)
+ > current_function_args_info.arg_count[(int) SH_ARG_INT]))
+ pretend_args = 0;
+ output_stack_adjust (-pretend_args
- current_function_args_info.stack_regs * 8,
stack_pointer_rtx, 0, NULL);
- extra_push = 0;
-
if (TARGET_SHCOMPACT && flag_pic && current_function_args_info.call_cookie)
/* We're going to use the PIC register to load the address of the
incoming-argument decoder and/or of the return trampoline from
@@ -5388,9 +5390,7 @@ sh_expand_prologue (void)
/* Emit the code for SETUP_VARARGS. */
if (current_function_stdarg)
{
- /* This is not used by the SH2E calling convention */
- if (TARGET_SH1 && ! TARGET_SH2E && ! TARGET_SH5
- && ! (TARGET_HITACHI || sh_cfun_attr_renesas_p ()))
+ if (TARGET_VARARGS_PRETEND_ARGS (current_function_decl))
{
/* Push arg regs as if they'd been provided by caller in stack. */
for (i = 0; i < NPARM_REGS(SImode); i++)
@@ -5404,7 +5404,6 @@ sh_expand_prologue (void)
break;
insn = push (rn);
RTX_FRAME_RELATED_P (insn) = 0;
- extra_push += 4;
}
}
}
@@ -5904,7 +5903,7 @@ sh_expand_epilogue (bool sibcall_p)
emit_insn (gen_toggle_sz ());
target_flags = save_flags;
- output_stack_adjust (extra_push + current_function_pretend_args_size
+ output_stack_adjust (current_function_pretend_args_size
+ save_size + d_rounding
+ current_function_args_info.stack_regs * 8,
stack_pointer_rtx, e, NULL);
@@ -6789,14 +6788,26 @@ sh_return_in_memory (tree type, tree fndecl)
later. Fortunately, we already have two flags that are part of struct
function that tell if a function uses varargs or stdarg. */
static void
-sh_setup_incoming_varargs (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED,
- int *pretend_arg_size ATTRIBUTE_UNUSED,
+sh_setup_incoming_varargs (CUMULATIVE_ARGS *ca,
+ enum machine_mode mode,
+ tree type,
+ int *pretend_arg_size,
int second_time ATTRIBUTE_UNUSED)
{
if (! current_function_stdarg)
abort ();
+ if (TARGET_VARARGS_PRETEND_ARGS (current_function_decl))
+ {
+ int named_parm_regs, anon_parm_regs;
+
+ named_parm_regs = (ROUND_REG (*ca, mode)
+ + (mode == BLKmode
+ ? ROUND_ADVANCE (int_size_in_bytes (type))
+ : ROUND_ADVANCE (GET_MODE_SIZE (mode))));
+ anon_parm_regs = NPARM_REGS (SImode) - named_parm_regs;
+ if (anon_parm_regs > 0)
+ *pretend_arg_size = anon_parm_regs * 4;
+ }
}
static bool
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index f6154a3..0d6d1c6 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -263,6 +263,11 @@ extern int target_flags;
#define TARGET_SAVE_ALL_TARGET_REGS (target_flags & SAVE_ALL_TR_BIT)
+/* This is not used by the SH2E calling convention */
+#define TARGET_VARARGS_PRETEND_ARGS(FUN_DECL) \
+ (TARGET_SH1 && ! TARGET_SH2E && ! TARGET_SH5 \
+ && ! (TARGET_HITACHI || sh_attr_renesas_p (FUN_DECL)))
+
#ifndef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT SELECT_SH1
#define SUPPORT_SH1