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_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_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_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_handler_block_trampoline (MonoTrampInfo **info, gboolean aot) { guint8 *tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD); guint8 *code, *buf; int tramp_size = 64; MonoJumpInfo *ji = NULL; GSList *unwind_ops = NULL; g_assert (!aot); code = buf = mono_global_codeman_reserve (tramp_size); /* * This trampoline restore the call chain of the handler block * then jumps into the code that deals with it. */ if (mono_get_jit_tls_offset () != -1) { s390_ear (code, s390_r1, 0); s390_sllg (code, s390_r1, s390_r1, 0, 32); s390_ear (code, s390_r1, 1); S390_SET (code, s390_r14, mono_get_jit_tls_offset()); s390_lg (code, s390_r14, s390_r1, 0, G_STRUCT_OFFSET(MonoJitTlsData, handler_block_return_address)); /* * Simulate a call */ S390_SET (code, s390_r1, tramp); s390_br (code, s390_r1); } else { /* * Slow path uses a C helper */ S390_SET (code, s390_r2, tramp); S390_SET (code, s390_r1, handler_block_trampoline_helper); s390_br (code, s390_r1); } mono_arch_flush_icache (buf, code - buf); if (mono_profiler_events & MONO_PROFILE_JIT_COMPILATION) mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_HELPER, NULL); g_assert (code - buf <= tramp_size); *info = mono_tramp_info_create ("handler_block_trampoline", buf, code - buf, ji, unwind_ops); return buf; }
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_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) { guint8 *code, *buf, *tramp; tramp = mono_get_trampoline_code (tramp_type); code = buf = mono_domain_code_reserve_align (domain, TRAMPOLINE_SIZE, 4); x86_push_imm (buf, arg1); x86_jump_code (buf, tramp); g_assert ((buf - code) <= TRAMPOLINE_SIZE); mono_arch_flush_icache (code, buf - code); MONO_PROFILER_RAISE (jit_code_buffer, (code, buf - code, MONO_PROFILER_CODE_BUFFER_SPECIFIC_TRAMPOLINE, mono_get_generic_trampoline_simple_name (tramp_type))); 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, *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; }