Example #1
0
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;
}	
Example #2
0
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;
}	
Example #3
0
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;
}	
Example #4
0
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;
}	
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
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;
}