+static gpointer
+get_win32_restore_stack (void)
+{
+ static guint8 *start = NULL;
+ guint8 *code;
+
+ if (start)
+ return start;
+
+ /* restore_stack (void) */
+ start = code = mono_global_codeman_reserve (128);
+
+ amd64_push_reg (code, AMD64_RBP);
+ amd64_mov_reg_reg (code, AMD64_RBP, AMD64_RSP, 8);
+
+ /* push 32 bytes of stack space for Win64 calling convention */
+ amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 32);
+
+ /* restore guard page */
+ amd64_mov_reg_imm (code, AMD64_R11, _resetstkoflw);
+ amd64_call_reg (code, AMD64_R11);
+
+ /* get jit_tls with context to restore */
+ amd64_mov_reg_imm (code, AMD64_R11, mono_tls_get_jit_tls);
+ amd64_call_reg (code, AMD64_R11);
+
+ /* move jit_tls from return reg to arg reg */
+ amd64_mov_reg_reg (code, AMD64_ARG_REG1, AMD64_RAX, 8);
+
+ /* retrieve pointer to saved context */
+ amd64_alu_reg_imm (code, X86_ADD, AMD64_ARG_REG1, MONO_STRUCT_OFFSET (MonoJitTlsData, stack_restore_ctx));
+
+ /* this call does not return */
+ amd64_mov_reg_imm (code, AMD64_R11, mono_restore_context);
+ amd64_call_reg (code, AMD64_R11);
+
+ g_assert ((code - start) < 128);
+
+ mono_arch_flush_icache (start, code - start);
+ MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL));
+
+ return start;
+}
+