summaryrefslogtreecommitdiff
path: root/libgcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'libgcc/config')
-rw-r--r--libgcc/config/rs6000/linux-unwind.h18
1 files changed, 10 insertions, 8 deletions
diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h
index 48009251fbc..20116326c3c 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