static void do_stack_magic (TrapFunction f, void *s, int has_retval) { #ifdef CAN_DO_STACK_MAGIC uaecptr a7; jmp_buf *j = (jmp_buf *)s; switch (setjmp (j[0])) { case 0: /* Returning directly */ current_extra_stack = s; if (has_retval == -1) { /*write_log ("finishing m68k mode return\n");*/ longjmp (j[1], 1); } /*write_log ("calling native function\n");*/ transfer_control (s, EXTRA_STACK_SIZE, stack_stub, f, has_retval); /* not reached */ return; case 1: /*write_log ("native function complete\n");*/ /* Returning normally. */ if (stack_has_retval (s, EXTRA_STACK_SIZE)) _68k_dreg (0) = get_retval_from_stack (s, EXTRA_STACK_SIZE); free_extra_stack (s); break; case 2: /* Returning to do a m68k call. We're now back on the main stack. */ a7 = _68k_areg(7) -= (sizeof (void *) + 7) & ~3; /* Save stack to restore */ *((void **)get_real_address (a7 + 4)) = s; /* Save special return address: this address contains a * calltrap that will longjmp to the right stack. */ put_long (_68k_areg (7), RTAREA_BASE + 0xFF00); _68k_setpc (m68k_calladdr); fill_prefetch_0 (); /*write_log ("native function calls m68k\n");*/ break; } current_extra_stack = 0; #endif }
static void do_stack_magic (TrapFunction f, struct extra_stack *s, int has_retval) { switch (setjmp (s->stackswap_env)) { case 0: /* Returning directly */ current_extra_stack = s; if (has_retval == -1) { /*write_log ("finishing m68k mode return\n");*/ longjmp (s->m68kcall_env, 1); } /*write_log ("calling native function\n");*/ transfer_control (s, EXTRA_STACK_SIZE, stack_stub, f, has_retval); /* not reached */ abort (); case 1: /*write_log ("native function complete\n");*/ /* Returning normally. */ if (stack_has_retval (s, EXTRA_STACK_SIZE)) m68k_dreg (regs, 0) = get_retval_from_stack (s, EXTRA_STACK_SIZE); free_extra_stack (s); break; case 2: { /* Returning to do a m68k call. We're now back on the main stack. */ uaecptr a7 = m68k_areg (regs, 7) -= (sizeof (void *) + 7) & ~3; /* Save stack to restore */ *((void **)get_real_address (a7 + 4)) = s; /* Save special return address: this address contains a * calltrap that will longjmp to the right stack. */ put_long (m68k_areg (regs, 7), RTAREA_BASE + 0xFF00); m68k_setpc (s->m68kcall_addr); fill_prefetch_slow (); /*write_log ("native function calls m68k\n");*/ break; } } current_extra_stack = 0; }