aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/sparc/sparc.h19
2 files changed, 23 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2c90a62..8482554 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2002-04-24 David S. Miller <davem@redhat.com>
+
+ PR target/6420
+ * config/sparc/sparc.h (FUNCTION_OK_FOR_SIBCALL): Return false if
+ 32-bit Sparc and current_function_returns_struct is true.
+
Wed Apr 24 13:48:25 CEST 2002 Jan Hubicka <jh@suse.cz>
* loop.c (canonicalize_condition): Use gen_int_mode.
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 4552132..872b1ee 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1902,8 +1902,23 @@ do { \
#define STRICT_ARGUMENT_NAMING TARGET_V9
/* We do not allow sibling calls if -mflat, nor
- we do not allow indirect calls to be optimized into sibling calls. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) (DECL && ! TARGET_FLAT)
+ we do not allow indirect calls to be optimized into sibling calls.
+
+ Also, on sparc 32-bit we cannot emit a sibling call when the
+ current function returns a structure. This is because the "unimp
+ after call" convention would cause the callee to return to the
+ wrong place. The generic code already disallows cases where the
+ function being called returns a structure.
+
+ It may seem strange how this last case could occur. Usually there
+ is code after the call which jumps to epilogue code which dumps the
+ return value into the struct return area. That ought to invalidate
+ the sibling call right? Well, in the c++ case we can end up passing
+ the pointer to the struct return area to a constructor (which returns
+ void) and then nothing else happens. Such a sibling call would look
+ valid without the added check here. */
+#define FUNCTION_OK_FOR_SIBCALL(DECL) \
+ (! TARGET_FLAT && (TARGET_ARCH64 || ! current_function_returns_struct))
/* Generate RTL to flush the register windows so as to make arbitrary frames
available. */