diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-24 23:49:22 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-24 23:49:22 +0000 |
commit | 0907e04de1a332df5c0cb3d8e46c4abb17f46f39 (patch) | |
tree | 8e87e0537093d0bf9cff3f150b0ff0fbc0170b16 /gcc/sibcall.c | |
parent | b3b27b2a4b1269ed3fb459a22bb0f60c135185ec (diff) | |
download | gcc-0907e04de1a332df5c0cb3d8e46c4abb17f46f39.tar.gz |
* sibcall.c (skip_pic_restore): New.
(identify_call_return_value): Use it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36596 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/sibcall.c')
-rw-r--r-- | gcc/sibcall.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/gcc/sibcall.c b/gcc/sibcall.c index 42a9d70fb81..eaf9ae76fe5 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; } |