+ case OP_TAILCALL: {
+ MonoCallInst *call = (MonoCallInst*)ins;
+ int pos = 0, i;
+
+ /* FIXME: no tracing support... */
+ if (cfg->prof_options & MONO_PROFILE_ENTER_LEAVE)
+ code = mono_arch_instrument_epilog (cfg, mono_profiler_method_leave, code, FALSE);
+ /* reset offset to make max_len work */
+ offset = code - cfg->native_code;
+
+ g_assert (!cfg->method->save_lmf);
+
+ //code = emit_load_volatile_arguments (cfg, code);
+
+ /* restore callee saved registers */
+ for (i = 0; i < X86_NREG; ++i)
+ if (X86_IS_CALLEE_SAVED_REG (i) && cfg->used_int_regs & (1 << i))
+ pos -= 4;
+ if (cfg->used_int_regs & (1 << X86_ESI)) {
+ x86_mov_reg_membase (code, X86_ESI, X86_EBP, pos, 4);
+ pos += 4;
+ }
+ if (cfg->used_int_regs & (1 << X86_EDI)) {
+ x86_mov_reg_membase (code, X86_EDI, X86_EBP, pos, 4);
+ pos += 4;
+ }
+ if (cfg->used_int_regs & (1 << X86_EBX)) {
+ x86_mov_reg_membase (code, X86_EBX, X86_EBP, pos, 4);
+ pos += 4;
+ }
+
+ /* Copy arguments on the stack to our argument area */
+ for (i = 0; i < call->stack_usage; i += 4) {
+ x86_mov_reg_membase (code, X86_EAX, X86_ESP, i, 4);
+ x86_mov_membase_reg (code, X86_EBP, 8 + i, X86_EAX, 4);
+ }
+
+ /* restore ESP/EBP */
+ x86_leave (code);
+ offset = code - cfg->native_code;
+ mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_METHOD_JUMP, ins->inst_p0);
+ x86_jump32 (code, 0);
+
+ cfg->disable_aot = TRUE;
+ break;
+ }