amd64_movsl (code);
/* now restore the registers from the LMF */
- NOT_IMPLEMENTED;
amd64_mov_reg_membase (code, AMD64_RCX, cont_reg, MONO_STRUCT_OFFSET (MonoContinuation, lmf), 8);
+ amd64_mov_reg_membase (code, AMD64_RBP, AMD64_RCX, MONO_STRUCT_OFFSET (MonoLMF, rbp), 8);
amd64_mov_reg_membase (code, AMD64_RSP, AMD64_RCX, MONO_STRUCT_OFFSET (MonoLMF, rsp), 8);
- /* restore the lmf chain */
- /*x86_mov_reg_membase (code, X86_ECX, X86_ESP, 12, 4);
- x86_mov_membase_reg (code, X86_ECX, 0, X86_EDX, 4);*/
+#ifdef WIN32
+ amd64_mov_reg_reg (code, AMD64_R14, AMD64_ARG_REG3, 8);
+#else
+ amd64_mov_reg_reg (code, AMD64_R12, AMD64_ARG_REG3, 8);
+#endif
/* state is already in rax */
amd64_jump_membase (code, cont_reg, MONO_STRUCT_OFFSET (MonoContinuation, return_ip));
/* the signature is: restore (MonoContinuation *cont, int state, MonoLMF **lmf_addr) */
/* put cont in edx */
x86_mov_reg_membase (code, X86_EDX, X86_ESP, 4, 4);
- /* state in eax, so it's setup as the return value */
- x86_mov_reg_membase (code, X86_EAX, X86_ESP, 8, 4);
+ /* state in eax, so it's setup as the return value */
+ x86_mov_reg_membase (code, X86_EAX, X86_ESP, 8, 4);
+ /* lmf_addr in ebx */
+ x86_mov_reg_membase(code, X86_EBX, X86_ESP, 0x0C, 4);
/* setup the copy of the stack */
x86_mov_reg_membase (code, X86_ECX, X86_EDX, MONO_STRUCT_OFFSET (MonoContinuation, stack_used_size), 4);
/* now restore the registers from the LMF */
x86_mov_reg_membase (code, X86_ECX, X86_EDX, MONO_STRUCT_OFFSET (MonoContinuation, lmf), 4);
- x86_mov_reg_membase (code, X86_EBX, X86_ECX, MONO_STRUCT_OFFSET (MonoLMF, ebx), 4);
x86_mov_reg_membase (code, X86_EBP, X86_ECX, MONO_STRUCT_OFFSET (MonoLMF, ebp), 4);
- x86_mov_reg_membase (code, X86_ESI, X86_ECX, MONO_STRUCT_OFFSET (MonoLMF, esi), 4);
- x86_mov_reg_membase (code, X86_EDI, X86_ECX, MONO_STRUCT_OFFSET (MonoLMF, edi), 4);
+ x86_mov_reg_membase (code, X86_ESP, X86_ECX, MONO_STRUCT_OFFSET (MonoLMF, esp), 4);
/* restore the lmf chain */
/*x86_mov_reg_membase (code, X86_ECX, X86_ESP, 12, 4);
for (i = 0; i < AMD64_NREG; ++i) {
if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->arch.saved_iregs & (1 << i))) {
/* Restore only used_int_regs, not arch.saved_iregs */
- if (cfg->used_int_regs & (1 << i)) {
+#if defined(MONO_SUPPORT_TASKLETS)
+ int restore_reg=1;
+#else
+ int restore_reg=(cfg->used_int_regs & (1 << i));
+#endif
+ if (restore_reg) {
amd64_mov_reg_membase (code, i, cfg->frame_reg, save_area_offset, 8);
mono_emit_unwind_op_same_value (cfg, code, i);
async_exc_point (code);
#define MINI_DEBUG(level,limit,code) do {if (G_UNLIKELY ((level) >= (limit))) code} while (0)
#endif
-#if !defined(DISABLE_TASKLETS) && defined(MONO_ARCH_SUPPORT_TASKLETS) && defined(__GNUC__)
+#if !defined(DISABLE_TASKLETS) && defined(MONO_ARCH_SUPPORT_TASKLETS)
+#if defined(__GNUC__)
#define MONO_SUPPORT_TASKLETS 1
+#elif defined(HOST_WIN32)
+#define MONO_SUPPORT_TASKLETS 1
+// Replace some gnu intrinsics needed for tasklets with MSVC equivalents.
+#define __builtin_extract_return_addr(x) x
+#define __builtin_return_address(x) _ReturnAddress()
+#define __builtin_frame_address(x) _AddressOfReturnAddress()
+#endif
#endif
#if ENABLE_LLVM
/* get to the frame that called Mark () */
memset (&rji, 0, sizeof (rji));
+ memset (&ctx, 0, sizeof (ctx));
do {
ji = mono_find_jit_info (cont->domain, jit_tls, &rji, NULL, &ctx, &new_ctx, NULL, &lmf, NULL, NULL);
if (!ji || ji == (gpointer)-1) {