aboutsummaryrefslogtreecommitdiff
path: root/gcc/sibcall.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>2000-09-24 16:49:22 -0700
committerRichard Henderson <rth@gcc.gnu.org>2000-09-24 16:49:22 -0700
commitfd442cef30223941cf09068241580e3d8f3fb7ae (patch)
tree8e87e0537093d0bf9cff3f150b0ff0fbc0170b16 /gcc/sibcall.c
parente1389cac8de5596ecf7729176e2410081e8ff288 (diff)
downloadgcc-fd442cef30223941cf09068241580e3d8f3fb7ae.zip
gcc-fd442cef30223941cf09068241580e3d8f3fb7ae.tar.gz
gcc-fd442cef30223941cf09068241580e3d8f3fb7ae.tar.bz2
sibcall.c (skip_pic_restore): New.
* sibcall.c (skip_pic_restore): New. (identify_call_return_value): Use it. From-SVN: r36596
Diffstat (limited to 'gcc/sibcall.c')
-rw-r--r--gcc/sibcall.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/gcc/sibcall.c b/gcc/sibcall.c
index 42a9d70..eaf9ae7 100644
--- a/gcc/sibcall.c
+++ b/gcc/sibcall.c
@@ -36,6 +36,7 @@ static int identify_call_return_value PARAMS ((rtx, rtx *, rtx *));
static rtx skip_copy_to_return_value PARAMS ((rtx, rtx, rtx));
static rtx skip_use_of_return_value PARAMS ((rtx, enum rtx_code));
static rtx skip_stack_adjustment PARAMS ((rtx));
+static rtx skip_pic_restore PARAMS ((rtx));
static rtx skip_jump_insn PARAMS ((rtx));
static int uses_addressof PARAMS ((rtx));
static int sequence_uses_addressof PARAMS ((rtx));
@@ -82,6 +83,11 @@ identify_call_return_value (cp, p_hard_return, p_soft_return)
if (! insn)
return 0;
+ /* Restore of GP register may appear here. */
+ insn = skip_pic_restore (insn);
+ if (! insn)
+ return 0;
+
/* If there's nothing after, there's no soft return value. */
insn = NEXT_INSN (insn);
if (! insn)
@@ -199,10 +205,6 @@ skip_stack_adjustment (orig_insn)
if (insn)
set = single_set (insn);
- /* The source must be the same as the current function's return value to
- ensure that any return value is put in the same place by the current
- function and the function we're calling. The destination register
- must be a pseudo. */
if (insn
&& set
&& GET_CODE (SET_SRC (set)) == PLUS
@@ -211,8 +213,26 @@ skip_stack_adjustment (orig_insn)
&& SET_DEST (set) == stack_pointer_rtx)
return insn;
- /* It did not look like a copy of the return value, so return the
- same insn we were passed. */
+ return orig_insn;
+}
+
+/* If the first real insn after ORIG_INSN sets the pic register,
+ return it. Otherwise return ORIG_INSN. */
+
+static rtx
+skip_pic_restore (orig_insn)
+ rtx orig_insn;
+{
+ rtx insn, set = NULL_RTX;
+
+ insn = next_nonnote_insn (orig_insn);
+
+ if (insn)
+ set = single_set (insn);
+
+ if (insn && set && SET_DEST (set) == pic_offset_table_rtx)
+ return insn;
+
return orig_insn;
}