2 * Licensed to the .NET Foundation under one or more agreements.
3 * The .NET Foundation licenses this file to you under the MIT license.
4 * See the LICENSE file in the project root for more information.
7 #include "mini-runtime.h"
9 #include <mono/metadata/abi-details.h>
12 mono_arch_patch_callsite (guint8
*method_start
, guint8
*code_ptr
, guint8
*addr
)
18 mono_arch_patch_plt_entry (guint8
*code
, gpointer
*got
, host_mgreg_t
*regs
, guint8
*addr
)
24 mono_arch_get_call_target (guint8
*code
)
31 mono_arch_get_plt_info_offset (guint8
*plt_entry
, host_mgreg_t
*regs
, guint8
*code
)
38 mono_arch_get_delegate_invoke_impls (void)
45 mono_arch_get_delegate_invoke_impl (MonoMethodSignature
*sig
, gboolean has_target
)
52 mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature
*sig
,
53 MonoMethod
*method
, int offset
,
54 gboolean load_imt_reg
)
63 mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type
, MonoTrampInfo
**info
,
69 guint8
*buf
= mono_global_codeman_reserve (1024), *code
= buf
;
72 const char *name
= mono_get_generic_trampoline_name (tramp_type
);
73 *info
= mono_tramp_info_create (name
, buf
, code
- buf
, NULL
, NULL
);
80 mono_arch_create_specific_trampoline (gpointer arg1
, MonoTrampolineType tramp_type
,
81 MonoDomain
*domain
, guint32
*code_len
)
83 guint8
*buf
= mono_domain_code_reserve (domain
, 64), *code
= buf
;
84 guint8
*tramp
= mono_get_trampoline_code (tramp_type
);
86 // Pass the argument in scratch t0.
87 code
= mono_riscv_emit_imm (code
, RISCV_T0
, (gsize
) arg1
);
88 code
= mono_riscv_emit_imm (code
, RISCV_T1
, (gsize
) tramp
);
89 riscv_jalr (code
, RISCV_ZERO
, RISCV_T1
, 0);
91 mono_arch_flush_icache (buf
, code
- buf
);
94 *code_len
= code
- buf
;
100 mono_arch_get_unbox_trampoline (MonoMethod
*m
, gpointer addr
)
102 guint8
*buf
= mono_domain_code_reserve (mono_domain_get (), 64), *code
= buf
;
104 // Pass the argument in a0.
105 code
= mono_riscv_emit_imm (code
, RISCV_A0
, sizeof (MonoObject
));
106 code
= mono_riscv_emit_imm (code
, RISCV_T0
, (gsize
) addr
);
107 riscv_jalr (code
, RISCV_ZERO
, RISCV_T0
, 0);
109 mono_arch_flush_icache (buf
, code
- buf
);
115 mono_arch_build_imt_trampoline (MonoVTable
*vtable
, MonoDomain
*domain
,
116 MonoIMTCheckItem
**imt_entries
, int count
,
124 mono_arch_get_static_rgctx_trampoline (gpointer arg
, gpointer addr
)
126 guint8
*buf
= mono_domain_code_reserve (mono_domain_get (), 64), *code
= buf
;
128 // Pass the argument in the RGCTX register.
129 code
= mono_riscv_emit_imm (code
, MONO_ARCH_RGCTX_REG
, (gsize
) arg
);
130 code
= mono_riscv_emit_imm (code
, RISCV_T0
, (gsize
) addr
);
131 riscv_jalr (code
, RISCV_ZERO
, RISCV_T0
, 0);
133 mono_arch_flush_icache (buf
, code
- buf
);
139 mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot
, MonoTrampInfo
**info
,
145 gboolean is_mrgctx
= MONO_RGCTX_SLOT_IS_MRGCTX (slot
);
146 int index
= MONO_RGCTX_SLOT_INDEX (slot
);
149 index
+= MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT
/ sizeof (target_mgreg_t
);
153 for (depth
= 0; ; depth
++) {
154 int size
= mono_class_rgctx_get_array_size (depth
, is_mrgctx
);
156 if (index
< size
- 1)
162 guint8
*buf
= mono_global_codeman_reserve (128 * depth
), *code
= buf
;
163 guint8
**null_jumps
= g_malloc0 (sizeof (guint8
*) * (depth
+ 2));
167 riscv_addi (code
, RISCV_T1
, RISCV_A0
, 0);
169 mono_arch_flush_icache (buf
, code
- buf
);
172 char *name
= mono_get_rgctx_fetch_trampoline_name (slot
);
173 *info
= mono_tramp_info_create (name
, buf
, code
- buf
, NULL
, NULL
);
181 mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo
**info
, gboolean aot
)
186 guint8
*buf
= mono_global_codeman_reserve (64), *code
= buf
;
189 * The RGCTX register holds a pointer to a <slot, trampoline address> pair.
190 * Load the trampoline address and branch to it. a0 holds the actual
191 * (M)RGCTX or VTable.
193 code
= mono_riscv_emit_load (code
, RISCV_T0
, MONO_ARCH_RGCTX_REG
, sizeof (target_mgreg_t
));
194 riscv_jalr (code
, RISCV_ZERO
, RISCV_T0
, 0);
196 mono_arch_flush_icache (buf
, code
- buf
);
199 *info
= mono_tramp_info_create ("rgctx_fetch_trampoline_general", buf
, code
- buf
, NULL
, NULL
);
205 mono_arch_create_sdb_trampoline (gboolean single_step
, MonoTrampInfo
**info
, gboolean aot
)
212 mono_arch_get_interp_to_native_trampoline (MonoTrampInfo
**info
)
219 mono_arch_get_native_to_interp_trampoline (MonoTrampInfo
**info
)
228 mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type
, MonoTrampInfo
**info
,
231 g_assert_not_reached ();
236 mono_arch_create_specific_trampoline (gpointer arg1
, MonoTrampolineType tramp_type
,
237 MonoDomain
*domain
, guint32
*code_len
)
239 g_assert_not_reached ();
244 mono_arch_get_unbox_trampoline (MonoMethod
*m
, gpointer addr
)
246 g_assert_not_reached ();
251 mono_arch_build_imt_trampoline (MonoVTable
*vtable
, MonoDomain
*domain
,
252 MonoIMTCheckItem
**imt_entries
, int count
,
255 g_assert_not_reached ();
260 mono_arch_get_static_rgctx_trampoline (gpointer arg
, gpointer addr
)
262 g_assert_not_reached ();
267 mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot
, MonoTrampInfo
**info
,
270 g_assert_not_reached ();
275 mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo
**info
, gboolean aot
)
277 g_assert_not_reached ();
282 mono_arch_create_sdb_trampoline (gboolean single_step
, MonoTrampInfo
**info
, gboolean aot
)
284 g_assert_not_reached ();
289 mono_arch_get_interp_to_native_trampoline (MonoTrampInfo
**info
)
291 g_assert_not_reached ();
296 mono_arch_get_native_to_interp_trampoline (MonoTrampInfo
**info
)
298 g_assert_not_reached ();