From f9ecc0359e6a4042600e7c5ef4dbb8fe0b3aafe3 Mon Sep 17 00:00:00 2001
From: bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 20 Nov 2006 12:40:57 +0000
Subject: [PATCH] 	* config/bfin/bfin.c (bfin_function_ok_for_sibcall):
 Handle some 	edge cases with local functions and TARGET_ID_SHARED_LIBRARY.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119013 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog          |  3 +++
 gcc/config/bfin/bfin.c | 23 ++++++++++++++++++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e18221307095..0dc55b7a366b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -25,6 +25,9 @@
 	(TARGET_SWITCHES): Add -mleaf-id-shared-library and -msep-data.
 	* doc/invoke.texi (Blackfin Options): Document new switches.
 
+	* config/bfin/bfin.c (bfin_function_ok_for_sibcall): Handle some
+	edge cases with local functions and TARGET_ID_SHARED_LIBRARY.
+
 2006-11-19  Andrew Pinski  <pinskia@gmail.com>
 
 	PR rtl-opt/29879
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 6238690d9c2b..b71b12374a16 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -1596,7 +1596,28 @@ bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
 			      tree exp ATTRIBUTE_UNUSED)
 {
   e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
-  return fkind == SUBROUTINE;
+  if (fkind != SUBROUTINE)
+    return false;
+  if (!TARGET_ID_SHARED_LIBRARY || TARGET_SEP_DATA)
+    return true;
+
+  /* When compiling for ID shared libraries, can't sibcall a local function
+     from a non-local function, because the local function thinks it does
+     not need to reload P5 in the prologue, but the sibcall wil pop P5 in the
+     sibcall epilogue, and we end up with the wrong value in P5.  */
+
+  if (!flag_unit_at_a_time || decl == NULL)
+    /* Not enough information.  */
+    return false;
+
+  {
+    struct cgraph_local_info *this_func, *called_func;
+    rtx addr, insn;
+ 
+    this_func = cgraph_local_info (current_function_decl);
+    called_func = cgraph_local_info (decl);
+    return !called_func->local || this_func->local;
+  }
 }
 
 /* Emit RTL insns to initialize the variable parts of a trampoline at
-- 
GitLab