diff options
author | Alan Modra <amodra@gmail.com> | 2011-08-02 00:35:24 +0930 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2011-08-02 00:35:24 +0930 |
commit | bd15e32c71b65cf399dfe72708b8ab3f35550dfe (patch) | |
tree | c6bcd1e86393045e79e0942fc18bb2e86285cf56 /libgcc | |
parent | 607d0635d893d141b3d4fd682b625df70b52a805 (diff) | |
download | gcc-bd15e32c71b65cf399dfe72708b8ab3f35550dfe.zip gcc-bd15e32c71b65cf399dfe72708b8ab3f35550dfe.tar.gz gcc-bd15e32c71b65cf399dfe72708b8ab3f35550dfe.tar.bz2 |
linux-unwind.h (frob_update_context <__powerpc64__>): Restore for indirect call bcrtl from correct stack slot...
libgcc/
* config/rs6000/linux-unwind.h (frob_update_context <__powerpc64__>):
Restore for indirect call bcrtl from correct stack slot, and only
if cfa+40 isn't valid.
gcc/
* config/rs6000/rs6000-protos.h (rs6000_save_toc_in_prologue_p): Delete.
* config/rs6000/rs6000.c (rs6000_save_toc_in_prologue_p): Make static.
(rs6000_emit_prologue): Don't prematurely return when
TARGET_SINGLE_PIC_BASE. Don't emit eh_frame info in
save_toc_in_prologue case.
(rs6000_call_indirect_aix): Only disallow save_toc_in_prologue for
calls_alloca.
From-SVN: r177041
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 6 | ||||
-rw-r--r-- | libgcc/config/rs6000/linux-unwind.h | 18 |
2 files changed, 16 insertions, 8 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 9108e46..1685c9f 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2011-08-02 Alan Modra <amodra@gmail.com> + + * config/rs6000/linux-unwind.h (frob_update_context <__powerpc64__>): + Restore for indirect call bcrtl from correct stack slot, and only + if cfa+40 isn't valid. + 2011-08-01 Julian Brown <julian@codesourcery.com> * config.host (arm*-*-linux*, arm*-*-uclinux*, arm*-*-eabi*) diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h index 4800925..20116326 100644 --- a/libgcc/config/rs6000/linux-unwind.h +++ b/libgcc/config/rs6000/linux-unwind.h @@ -354,20 +354,22 @@ frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs ATT /* We are in a plt call stub or r2 adjusting long branch stub, before r2 has been saved. Keep REG_UNSAVED. */ } - else if (pc[0] == 0x4E800421 - && pc[1] == 0xE8410028) - { - /* We are at the bctrl instruction in a call via function - pointer. gcc always emits the load of the new r2 just - before the bctrl. */ - _Unwind_SetGRPtr (context, 2, context->cfa + 40); - } else { unsigned int *insn = (unsigned int *) _Unwind_GetGR (context, R_LR); if (insn && *insn == 0xE8410028) _Unwind_SetGRPtr (context, 2, context->cfa + 40); + else if (pc[0] == 0x4E800421 + && pc[1] == 0xE8410028) + { + /* We are at the bctrl instruction in a call via function + pointer. gcc always emits the load of the new R2 just + before the bctrl so this is the first and only place + we need to use the stored R2. */ + _Unwind_Word sp = _Unwind_GetGR (context, 1); + _Unwind_SetGRPtr (context, 2, sp + 40); + } } } #endif |