gpointer mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr) { guint8 *code, *start; int buf_len; GSList *unwind_ops; MonoDomain *domain = mono_domain_get (); buf_len = 10; start = code = mono_domain_code_reserve (domain, buf_len); unwind_ops = mono_arch_get_cie_program (); x86_mov_reg_imm (code, MONO_ARCH_RGCTX_REG, arg); x86_jump_code (code, addr); g_assert ((code - start) <= buf_len); mono_arch_flush_icache (start, code - start); MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL)); mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain); return start; }
gpointer mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) { guint8 *code, *buf, *tramp; gint32 displace; tramp = mono_get_trampoline_code (tramp_type); /*----------------------------------------------------------*/ /* This is the method-specific part of the trampoline. Its */ /* purpose is to provide the generic part with the */ /* MonoMethod *method pointer. We'll use r1 to keep it. */ /*----------------------------------------------------------*/ code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE); s390_basr (buf, s390_r1, 0); s390_j (buf, 6); s390_llong(buf, arg1); s390_lg (buf, s390_r1, 0, s390_r1, 4); displace = (tramp - buf) / 2; s390_jcl (buf, S390_CC_UN, displace); /* Flush instruction cache, since we've generated code */ mono_arch_flush_icache (code, buf - code); /* Sanity check */ g_assert ((buf - code) <= SPECIFIC_TRAMPOLINE_SIZE); if (code_len) *code_len = buf - code; return code; }
gpointer mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr) { guint8 *code, *start; gint32 displace; int buf_len; char trampName[128]; MonoDomain *domain = mono_domain_get (); buf_len = 32; start = code = mono_domain_code_reserve (domain, buf_len); S390_SET (code, MONO_ARCH_RGCTX_REG, mrgctx); displace = ((uintptr_t) addr - (uintptr_t) code) / 2; s390_jg (code, displace); g_assert ((code - start) < buf_len); mono_arch_flush_icache (start, code - start); if (mono_profiler_events & MONO_PROFILE_JIT_COMPILATION) mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL); snprintf(trampName, sizeof(trampName), "%s_rgctx_trampoline", m->name); mono_tramp_info_register (mono_tramp_info_create (trampName, start, code - start, NULL, NULL), domain); return(start); }
gpointer mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr) { guint8 *code, *start; gint32 displace; int buf_len; MonoDomain *domain = mono_domain_get (); buf_len = 32; start = code = mono_domain_code_reserve (domain, buf_len); s390_basr (code, s390_r1, 0); s390_j (code, 6); s390_llong(code, mrgctx); s390_lg (code, MONO_ARCH_RGCTX_REG, 0, s390_r1, 4); displace = ((uintptr_t) addr - (uintptr_t) code) / 2; s390_jg (code, displace); g_assert ((code - start) < buf_len); mono_arch_flush_icache (start, code - start); return(start); }
gpointer mono_arch_get_unbox_trampoline (MonoMethod *method, gpointer addr) { guint8 *code, *start; int this_pos = s390_r2; MonoDomain *domain = mono_domain_get (); char trampName[128]; start = code = mono_domain_code_reserve (domain, 28); S390_SET (code, s390_r1, addr); s390_aghi (code, this_pos, MONO_ABI_SIZEOF (MonoObject)); s390_br (code, s390_r1); g_assert ((code - start) <= 28); mono_arch_flush_icache (start, code - start); MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, method)); snprintf(trampName, sizeof(trampName), "%s_unbox_trampoline", method->name); mono_tramp_info_register (mono_tramp_info_create (trampName, start, code - start, NULL, NULL), domain); return start; }
gpointer mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) { guint32 *code, *buf, *tramp; tramp = mono_get_trampoline_code (tramp_type); code = buf = mono_domain_code_reserve (domain, TRAMPOLINE_SIZE * 4); /* We have to use g5 here because there is no other free register */ sparc_set (code, tramp, sparc_g5); sparc_jmpl (code, sparc_g5, sparc_g0, sparc_g5); sparc_nop (code); #ifdef SPARCV9 g_assert_not_reached (); #else *code = (guint32)arg1; code ++; #endif g_assert ((code - buf) <= TRAMPOLINE_SIZE); if (code_len) *code_len = (code - buf) * 4; mono_arch_flush_icache ((guint8*)buf, (code - buf) * 4); return buf; }
gpointer mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr) { guint8 *code, *start; gint32 displace; int buf_len; MonoDomain *domain = mono_domain_get (); buf_len = 32; start = code = mono_domain_code_reserve (domain, buf_len); S390_SET (code, MONO_ARCH_RGCTX_REG, mrgctx); displace = ((uintptr_t) addr - (uintptr_t) code) / 2; s390_jg (code, displace); g_assert ((code - start) < buf_len); mono_arch_flush_icache (start, code - start); mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL); return(start); }
gpointer mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr) { guint8 *code, *start; gint32 displace; int buf_len; MonoDomain *domain = mono_domain_get (); buf_len = 32; start = code = mono_domain_code_reserve (domain, buf_len); S390_SET (code, MONO_ARCH_RGCTX_REG, arg); displace = ((uintptr_t) addr - (uintptr_t) code) / 2; s390_jg (code, displace); g_assert ((code - start) < buf_len); mono_arch_flush_icache (start, code - start); MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL)); mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain); return(start); }
gpointer mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) { guint8 *code, *buf, *tramp; gint32 displace; tramp = mono_get_trampoline_code (tramp_type); /*----------------------------------------------------------*/ /* This is the method-specific part of the trampoline. Its */ /* purpose is to provide the generic part with the */ /* MonoMethod *method pointer. We'll use r1 to keep it. */ /*----------------------------------------------------------*/ code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE); S390_SET (buf, s390_r1, arg1); displace = (tramp - buf) / 2; s390_jg (buf, displace); /* Flush instruction cache, since we've generated code */ mono_arch_flush_icache (code, buf - code); MONO_PROFILER_RAISE (jit_code_buffer, (buf, code - buf, MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE, (void *) mono_get_generic_trampoline_simple_name (tramp_type))); /* Sanity check */ g_assert ((buf - code) <= SPECIFIC_TRAMPOLINE_SIZE); if (code_len) *code_len = buf - code; return code; }
gpointer mono_arch_get_unbox_trampoline (MonoGenericSharingContext *gsctx, MonoMethod *method, gpointer addr) { guint8 *code, *start; int this_pos = s390_r2; MonoDomain *domain = mono_domain_get (); start = addr; if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret)) this_pos = s390_r3; start = code = mono_domain_code_reserve (domain, 28); s390_basr (code, s390_r13, 0); s390_j (code, 4); s390_word (code, addr); s390_l (code, s390_r1, 0, s390_r13, 4); s390_ahi (code, this_pos, sizeof(MonoObject)); s390_br (code, s390_r1); g_assert ((code - start) <= 28); mono_arch_flush_icache (start, code - start); return start; }
gpointer mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr) { guint8 *buf = mono_domain_code_reserve (mono_domain_get (), 64), *code = buf; // Pass the argument in a0. code = mono_riscv_emit_imm (code, RISCV_A0, sizeof (MonoObject)); code = mono_riscv_emit_imm (code, RISCV_T0, (gsize) addr); riscv_jalr (code, RISCV_ZERO, RISCV_T0, 0); mono_arch_flush_icache (buf, code - buf); return buf; }
gpointer mono_arch_get_static_rgctx_trampoline (gpointer arg, gpointer addr) { guint8 *buf = mono_domain_code_reserve (mono_domain_get (), 64), *code = buf; // Pass the argument in the RGCTX register. code = mono_riscv_emit_imm (code, MONO_ARCH_RGCTX_REG, (gsize) arg); code = mono_riscv_emit_imm (code, RISCV_T0, (gsize) addr); riscv_jalr (code, RISCV_ZERO, RISCV_T0, 0); mono_arch_flush_icache (buf, code - buf); return buf; }
gpointer mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) { guint8 *code, *buf, *tramp; gint32 displace; tramp = mono_get_trampoline_code (tramp_type); /*----------------------------------------------------------*/ /* This is the method-specific part of the trampoline. Its */ /* purpose is to provide the generic part with the */ /* MonoMethod *method pointer. We'll use r1 to keep it. */ /*----------------------------------------------------------*/ code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE); switch (tramp_type) { /* * Monitor tramps have the object in r2 */ case MONO_TRAMPOLINE_MONITOR_ENTER: case MONO_TRAMPOLINE_MONITOR_ENTER_V4: case MONO_TRAMPOLINE_MONITOR_EXIT: s390_lgr (buf, s390_r1, s390_r2); break; /* * Generic class trampoline arg is in r2 */ case MONO_TRAMPOLINE_GENERIC_CLASS_INIT: s390_lgr (buf, s390_r1, s390_r2); break; default : S390_SET (buf, s390_r1, arg1); } displace = (tramp - buf) / 2; s390_jg (buf, displace); /* Flush instruction cache, since we've generated code */ mono_arch_flush_icache (code, buf - code); mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE, (void *) mono_get_generic_trampoline_simple_name (tramp_type)); /* Sanity check */ g_assert ((buf - code) <= SPECIFIC_TRAMPOLINE_SIZE); if (code_len) *code_len = buf - code; return code; }
gpointer mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) { guint8 *buf = mono_domain_code_reserve (domain, 64), *code = buf; guint8 *tramp = mono_get_trampoline_code (tramp_type); // Pass the argument in scratch t0. code = mono_riscv_emit_imm (code, RISCV_T0, (gsize) arg1); code = mono_riscv_emit_imm (code, RISCV_T1, (gsize) tramp); riscv_jalr (code, RISCV_ZERO, RISCV_T1, 0); mono_arch_flush_icache (buf, code - buf); if (code_len) *code_len = code - buf; return buf; }
gpointer mono_arch_get_unbox_trampoline (MonoMethod *method, gpointer addr) { guint8 *code, *start; int this_pos = s390_r2; MonoDomain *domain = mono_domain_get (); start = code = mono_domain_code_reserve (domain, 28); S390_SET (code, s390_r1, addr); s390_aghi (code, this_pos, sizeof(MonoObject)); s390_br (code, s390_r1); g_assert ((code - start) <= 28); mono_arch_flush_icache (start, code - start); return start; }
gpointer mono_arch_get_unbox_trampoline (MonoMethod *method, gpointer addr) { guint8 *code, *start; int this_pos = s390_r2; MonoDomain *domain = mono_domain_get (); start = code = mono_domain_code_reserve (domain, 28); S390_SET (code, s390_r1, addr); s390_aghi (code, this_pos, sizeof(MonoObject)); s390_br (code, s390_r1); g_assert ((code - start) <= 28); mono_arch_flush_icache (start, code - start); mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, method); return start; }
/* * mono_arch_get_gsharedvt_arg_trampoline: * * See tramp-x86.c for documentation. */ gpointer mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr) { guint8 *code, *start; int buf_len; buf_len = 32; start = code = mono_domain_code_reserve (domain, buf_len); amd64_mov_reg_imm (code, AMD64_RAX, arg); amd64_jump_code (code, addr); g_assert ((code - start) < buf_len); mono_arch_flush_icache (start, code - start); mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL); mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain); return start; }
gpointer mono_arch_get_unbox_trampoline (MonoGenericSharingContext *gsctx, MonoMethod *method, gpointer addr) { guint8 *code, *start; int this_pos = s390_r2; MonoDomain *domain = mono_domain_get (); start = code = mono_domain_code_reserve (domain, 28); s390_basr (code, s390_r1, 0); s390_j (code, 6); s390_llong(code, addr); s390_lg (code, s390_r1, 0, s390_r1, 4); s390_aghi (code, this_pos, sizeof(MonoObject)); s390_br (code, s390_r1); g_assert ((code - start) <= 28); mono_arch_flush_icache (start, code - start); return start; }
/* * mono_arch_get_unbox_trampoline: * @m: method pointer * @addr: pointer to native code for @m * * when value type methods are called through the vtable we need to unbox the * this argument. This method returns a pointer to a trampoline which does * unboxing before calling the method */ gpointer mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr) { guint8 *code, *start; int this_pos = 4, size = 16; MonoDomain *domain = mono_domain_get (); GSList *unwind_ops; start = code = mono_domain_code_reserve (domain, size); unwind_ops = mono_arch_get_cie_program (); x86_alu_membase_imm (code, X86_ADD, X86_ESP, this_pos, MONO_ABI_SIZEOF (MonoObject)); x86_jump_code (code, addr); g_assert ((code - start) < size); MONO_PROFILER_RAISE (jit_code_buffer, (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m)); mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain); return start; }
gpointer mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) { guint8 *buf, *tramp; gint64 disp; Ia64CodegenState code; tramp = mono_get_trampoline_code (tramp_type); buf = mono_domain_code_reserve (domain, TRAMPOLINE_SIZE); /* FIXME: Optimize this */ ia64_codegen_init (code, buf); ia64_movl (code, GP_SCRATCH_REG, arg1); ia64_begin_bundle (code); disp = (tramp - code.buf) >> 4; if (ia64_is_imm21 (disp)) { ia64_br_cond (code, disp); } else { ia64_movl (code, GP_SCRATCH_REG2, tramp); ia64_mov_to_br (code, IA64_B6, GP_SCRATCH_REG2); ia64_br_cond_reg (code, IA64_B6); } ia64_codegen_close (code); g_assert (code.buf - buf <= TRAMPOLINE_SIZE); mono_arch_flush_icache (buf, code.buf - buf); if (code_len) *code_len = code.buf - buf; return buf; }
/* * mono_arch_get_unbox_trampoline: * @m: method pointer * @addr: pointer to native code for @m * * when value type methods are called through the vtable we need to unbox the * this argument. This method returns a pointer to a trampoline which does * unboxing before calling the method */ gpointer mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr) { guint8 *buf; gpointer func_addr, func_gp; Ia64CodegenState code; int this_reg = 0; gpointer *desc; MonoDomain *domain = mono_domain_get (); /* FIXME: Optimize this */ func_addr = ((gpointer*)addr) [0]; func_gp = ((gpointer*)addr) [1]; buf = mono_domain_code_reserve (domain, 256); /* Since the this reg is a stacked register, its a bit hard to access it */ ia64_codegen_init (code, buf); ia64_alloc (code, 40, 8, 1, 0, 0); ia64_adds_imm (code, 32 + this_reg, sizeof (MonoObject), 32 + this_reg); ia64_mov_to_ar_i (code, IA64_PFS, 40); ia64_movl (code, GP_SCRATCH_REG, func_addr); ia64_mov_to_br (code, IA64_B6, GP_SCRATCH_REG); ia64_br_cond_reg (code, IA64_B6); ia64_codegen_close (code); g_assert (code.buf - buf < 256); mono_arch_flush_icache (buf, code.buf - buf); /* FIXME: */ desc = g_malloc0 (sizeof (gpointer) * 2); desc [0] = buf; desc [1] = func_gp; return desc; }