aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2011-08-02 00:35:24 +0930
committerAlan Modra <amodra@gcc.gnu.org>2011-08-02 00:35:24 +0930
commitbd15e32c71b65cf399dfe72708b8ab3f35550dfe (patch)
treec6bcd1e86393045e79e0942fc18bb2e86285cf56 /libgcc
parent607d0635d893d141b3d4fd682b625df70b52a805 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--libgcc/config/rs6000/linux-unwind.h18
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