static guint8 bitmask;
guint8 *jump;
+ g_assert (ins->sreg1 == MONO_AMD64_ARG_REG1);
+
if (byte_offset < 0)
mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
jump = code;
amd64_branch8 (code, X86_CC_NZ, -1, 1);
- if (ins->sreg1 != MONO_AMD64_ARG_REG1)
- amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, ins->sreg1, 8);
code = emit_call (cfg, code, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_generic_class_init", FALSE);
ins->flags |= MONO_INST_GC_CALLSITE;
ins->backend.pc_offset = code - cfg->native_code;
mono_sigctx_to_monoctx (sigctx, &ctx);
- rip = (guint8*)ctx.rip;
+ rip = (guint8*)ctx.gregs [AMD64_RIP];
if (IS_REX (rip [0])) {
reg = amd64_rex_b (rip [0]);
/* idiv REG */
reg += x86_modrm_rm (rip [1]);
- switch (reg) {
- case AMD64_RAX:
- value = ctx.rax;
- break;
- case AMD64_RBX:
- value = ctx.rbx;
- break;
- case AMD64_RCX:
- value = ctx.rcx;
- break;
- case AMD64_RDX:
- value = ctx.rdx;
- break;
- case AMD64_RBP:
- value = ctx.rbp;
- break;
- case AMD64_RSP:
- value = ctx.rsp;
- break;
- case AMD64_RSI:
- value = ctx.rsi;
- break;
- case AMD64_RDI:
- value = ctx.rdi;
- break;
- case AMD64_R12:
- value = ctx.r12;
- break;
- case AMD64_R13:
- value = ctx.r13;
- break;
- case AMD64_R14:
- value = ctx.r14;
- break;
- case AMD64_R15:
- value = ctx.r15;
- break;
- default:
- g_assert_not_reached ();
- reg = -1;
- }
+ value = ctx.gregs [reg];
if (value == -1)
return TRUE;
return start;
}
+#define MAX_VIRTUAL_DELEGATE_OFFSET 32
+
+static gpointer
+get_delegate_virtual_invoke_impl (gboolean load_imt_reg, int offset, guint32 *code_len)
+{
+ guint8 *code, *start;
+ int size = 20;
+
+ if (offset / sizeof (gpointer) > MAX_VIRTUAL_DELEGATE_OFFSET)
+ return NULL;
+
+ start = code = mono_global_codeman_reserve (size);
+
+ /* Replace the this argument with the target */
+ amd64_mov_reg_reg (code, AMD64_RAX, AMD64_ARG_REG1, 8);
+ amd64_mov_reg_membase (code, AMD64_ARG_REG1, AMD64_RAX, MONO_STRUCT_OFFSET (MonoDelegate, target), 8);
+
+ if (load_imt_reg) {
+ /* Load the IMT reg */
+ amd64_mov_reg_membase (code, MONO_ARCH_IMT_REG, AMD64_RAX, MONO_STRUCT_OFFSET (MonoDelegate, method), 8);
+ }
+
+ /* Load the vtable */
+ amd64_mov_reg_membase (code, AMD64_RAX, AMD64_ARG_REG1, MONO_STRUCT_OFFSET (MonoObject, vtable), 8);
+ amd64_jump_membase (code, AMD64_RAX, offset);
+ mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
+
+ if (code_len)
+ *code_len = code - start;
+
+ return start;
+}
+
/*
* mono_arch_get_delegate_invoke_impls:
*
g_free (tramp_name);
}
+ for (i = 0; i < MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
+ code = get_delegate_virtual_invoke_impl (TRUE, i * SIZEOF_VOID_P, &code_len);
+ tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", i);
+ res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
+ g_free (tramp_name);
+
+ code = get_delegate_virtual_invoke_impl (FALSE, i * SIZEOF_VOID_P, &code_len);
+ tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", i);
+ res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
+ g_free (tramp_name);
+ }
+
return res;
}
gpointer
mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
{
- guint8 *code, *start;
- int size = 20;
-
- start = code = mono_global_codeman_reserve (size);
-
- /* Replace the this argument with the target */
- amd64_mov_reg_reg (code, AMD64_RAX, AMD64_ARG_REG1, 8);
- amd64_mov_reg_membase (code, AMD64_ARG_REG1, AMD64_RAX, MONO_STRUCT_OFFSET (MonoDelegate, target), 8);
-
- if (load_imt_reg) {
- /* Load the IMT reg */
- amd64_mov_reg_membase (code, MONO_ARCH_IMT_REG, AMD64_RAX, MONO_STRUCT_OFFSET (MonoDelegate, method), 8);
- }
-
- /* Load the vtable */
- amd64_mov_reg_membase (code, AMD64_RAX, AMD64_ARG_REG1, MONO_STRUCT_OFFSET (MonoObject, vtable), 8);
- amd64_jump_membase (code, AMD64_RAX, offset);
- mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
-
- return start;
+ return get_delegate_virtual_invoke_impl (load_imt_reg, offset, NULL);
}
void
return 0;
}
-#define _CTX_REG(ctx,fld,i) ((&ctx->fld)[i])
-
mgreg_t
mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
{
- switch (reg) {
- case AMD64_RCX: return ctx->rcx;
- case AMD64_RDX: return ctx->rdx;
- case AMD64_RBX: return ctx->rbx;
- case AMD64_RBP: return ctx->rbp;
- case AMD64_RSP: return ctx->rsp;
- default:
- return _CTX_REG (ctx, rax, reg);
- }
+ return ctx->gregs [reg];
}
void
mono_arch_context_set_int_reg (MonoContext *ctx, int reg, mgreg_t val)
{
- switch (reg) {
- case AMD64_RCX:
- ctx->rcx = val;
- break;
- case AMD64_RDX:
- ctx->rdx = val;
- break;
- case AMD64_RBX:
- ctx->rbx = val;
- break;
- case AMD64_RBP:
- ctx->rbp = val;
- break;
- case AMD64_RSP:
- ctx->rsp = val;
- break;
- default:
- _CTX_REG (ctx, rax, reg) = val;
- }
+ ctx->gregs [reg] = val;
}
gpointer