- memcpy (&new_ctx->fregs, (char*)sframe->sp - sizeof (double) * MONO_SAVED_FREGS, sizeof (double) * MONO_SAVED_FREGS);
- memcpy (&new_ctx->regs, (char*)sframe->sp - sizeof (double) * MONO_SAVED_FREGS - sizeof (gulong) * MONO_SAVED_GREGS, sizeof (gulong) * MONO_SAVED_GREGS);
- } else if (ji->used_regs) {
- /* keep updated with emit_prolog in mini-ppc.c */
- offset = 0;
- /* FIXME handle floating point args
- for (i = 31; i >= 14; --i) {
- if (ji->used_fregs & (1 << i)) {
- offset += sizeof (double);
- new_ctx->fregs [i - 14] = *(gulong*)((char*)sframe->sp - offset);
- }
- }*/
- for (i = 31; i >= 13; --i) {
- if (ji->used_regs & (1 << i)) {
- offset += sizeof (gulong);
- new_ctx->regs [i - 13] = *(gulong*)((char*)sframe->sp - offset);
- }
- }
+ /* sframe->sp points just past the end of the LMF */
+ guint8 *lmf_addr = (guint8*)sframe->sp - sizeof (MonoLMF);
+ memcpy (&new_ctx->fregs, lmf_addr + G_STRUCT_OFFSET (MonoLMF, fregs), sizeof (double) * MONO_SAVED_FREGS);
+ memcpy (&new_ctx->regs, lmf_addr + G_STRUCT_OFFSET (MonoLMF, iregs), sizeof (mgreg_t) * MONO_SAVED_GREGS);
+ /* the calling IP is in the parent frame */
+ sframe = (MonoPPCStackFrame*)sframe->sp;
+ /* we substract 4, so that the IP points into the call instruction */
+ MONO_CONTEXT_SET_IP (new_ctx, sframe->lr - 4);
+ } else {
+ regs [ppc_lr] = ctx->sc_ir;
+ regs [ppc_sp] = ctx->sc_sp;
+ for (i = 0; i < MONO_SAVED_GREGS; ++i)
+ regs [ppc_r13 + i] = ctx->regs [i];
+
+ mono_unwind_frame (unwind_info, unwind_info_len, ji->code_start,
+ (guint8*)ji->code_start + ji->code_size,
+ ip, regs, MONO_MAX_IREGS + 1, &cfa);
+
+ /* we substract 4, so that the IP points into the call instruction */
+ MONO_CONTEXT_SET_IP (new_ctx, regs [ppc_lr] - 4);
+ MONO_CONTEXT_SET_BP (new_ctx, cfa);
+
+ for (i = 0; i < MONO_SAVED_GREGS; ++i)
+ new_ctx->regs [i] = regs [ppc_r13 + i];