aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/sparc/sparc.c14
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/sparc/sibcall-dslot.c11
4 files changed, 28 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a1c3658..3176285 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2010-08-20 Olivier Hainque <hainque@adacore.com>
+
+ * config/sparc/sparc.c (sparc_asm_function_epilogue): Don't output
+ an extra nop past a sibling call at the very end.
+
2010-08-19 Bernd Schmidt <bernds@codesourcery.com>
PR bootstrap/45350
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index ef1dd73..50b981e 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -4527,11 +4527,11 @@ sparc_can_use_return_insn_p (void)
static void
sparc_asm_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
- /* If code does not drop into the epilogue, we have to still output
- a dummy nop for the sake of sane backtraces. Otherwise, if the
- last two instructions of a function were "call foo; dslot;" this
- can make the return PC of foo (i.e. address of call instruction
- plus 8) point to the first instruction in the next function. */
+ /* If the last two instructions of a function are "call foo; dslot;"
+ the return address might point to the first instruction in the next
+ function and we have to output a dummy nop for the sake of sane
+ backtraces in such cases. This is pointless for sibling calls since
+ the return address is explicitly adjusted. */
rtx insn, last_real_insn;
@@ -4543,7 +4543,9 @@ sparc_asm_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
&& GET_CODE (PATTERN (last_real_insn)) == SEQUENCE)
last_real_insn = XVECEXP (PATTERN (last_real_insn), 0, 0);
- if (last_real_insn && GET_CODE (last_real_insn) == CALL_INSN)
+ if (last_real_insn
+ && CALL_P (last_real_insn)
+ && !SIBLING_CALL_P (last_real_insn))
fputs("\tnop\n", file);
sparc_output_deferred_case_vectors ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e8bbfc1..e46fd3f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2010-10-19 Olivier Hainque <hainque@adacore.com>
+
+ * gcc.target/sparc/sibcall-dslot.c: New testcase.
+
2010-08-19 Jason Merrill <jason@redhat.com>
* g++.dg/init/synth3.C: New.
diff --git a/gcc/testsuite/gcc.target/sparc/sibcall-dslot.c b/gcc/testsuite/gcc.target/sparc/sibcall-dslot.c
new file mode 100644
index 0000000..db34016
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sparc/sibcall-dslot.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern int one ();
+
+int some_n ()
+{
+ return one ();
+}
+
+/* { dg-final { scan-assembler-not "nop" } } */