Skip to content

Commit aefdc63

Browse files
authored
[RISC-V] Port Mono for RISC-V 64 Arch (2/3) thunk & tramponlie (#83715)
* thunk & tramponlie for riscv64, also exception call * format
1 parent c93a93b commit aefdc63

File tree

4 files changed

+1101
-74
lines changed

4 files changed

+1101
-74
lines changed

src/mono/mono/arch/riscv/riscv-codegen.h

+14
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,20 @@ enum {
614614
((funct5) << 27)); \
615615
} while (0)
616616

617+
static G_GNUC_UNUSED inline gboolean
618+
riscv_is_jal_disp (void *code, void *target)
619+
{
620+
gint64 disp = ((char *)(target) - (char *)(code)) / 2;
621+
622+
return (disp > -(1 << 19)) && (disp < (1 << 19));
623+
}
624+
625+
static G_GNUC_UNUSED inline gsize
626+
riscv_get_jal_disp (void *code, void *target)
627+
{
628+
return ((char *)(target) - (char *)(code)) & 0xfffffffe;
629+
}
630+
617631
/*
618632
* NOTE: When you add new codegen macros or change existing ones, you must
619633
* expand riscv-codegen-test.c to cover them, and update riscv-codegen.exp32

src/mono/mono/mini/exceptions-riscv.c

+34-9
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,14 @@ mono_arch_exceptions_init (void)
147147
// NOT_IMPLEMENTED;
148148
}
149149

150+
/*
151+
* mono_arch_unwind_frame:
152+
*
153+
* This function is used to gather information from @ctx, and store it in @frame_info.
154+
* It unwinds one stack frame, and stores the resulting context into @new_ctx. @lmf
155+
* is modified if needed.
156+
* Returns TRUE on success, FALSE otherwise.
157+
*/
150158
gboolean
151159
mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji,
152160
MonoContext *ctx, MonoContext *new_ctx, MonoLMF **lmf,
@@ -160,7 +168,7 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji,
160168
*new_ctx = *ctx;
161169

162170
if (ji != NULL) {
163-
NOT_IMPLEMENTED;
171+
// all GREG + Callee saved FREG
164172
host_mgreg_t regs [MONO_MAX_IREGS + 12 + 1];
165173
guint8 *cfa;
166174
guint32 unwind_info_len;
@@ -182,10 +190,9 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji,
182190
for (int i = 0; i < 10; i++)
183191
(regs + MONO_MAX_IREGS) [i] = *((host_mgreg_t*)&new_ctx->fregs [RISCV_F18 + i]);
184192

185-
gboolean success = mono_unwind_frame (unwind_info, unwind_info_len, (guint8*)ji->code_start,
186-
(guint8*)ji->code_start + ji->code_size,
187-
(guint8*)ip, NULL, regs, MONO_MAX_IREGS + 8,
188-
save_locations, MONO_MAX_IREGS, (guint8**)&cfa);
193+
gboolean success = mono_unwind_frame (unwind_info, unwind_info_len, (guint8 *)ji->code_start,
194+
(guint8 *)ji->code_start + ji->code_size, (guint8 *)ip, NULL, regs,
195+
MONO_MAX_IREGS + 12 + 1, save_locations, MONO_MAX_IREGS, (guint8 **)&cfa);
189196

190197
if (!success)
191198
return FALSE;
@@ -198,15 +205,33 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji,
198205

199206
new_ctx->gregs [RISCV_SP] = (host_mgreg_t)(gsize)cfa;
200207

201-
if (*lmf)
202-
NOT_IMPLEMENTED;
208+
if (*lmf && (*lmf)->gregs [RISCV_FP] && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->gregs [RISCV_SP])) {
209+
/* remove any unused lmf */
210+
*lmf = (MonoLMF *)(((gsize)(*lmf)->previous_lmf) & ~(TARGET_SIZEOF_VOID_P - 1));
211+
}
203212

204-
/* we subtract 1, so that the IP points into the call instruction */
213+
/* we substract 1, so that the pc points into the call instruction */
205214
new_ctx->gregs [RISCV_ZERO]--;
206215

207216
return TRUE;
208217
} else if (*lmf) {
209-
NOT_IMPLEMENTED;
218+
g_assert ((((guint64)(*lmf)->previous_lmf) & 2) == 0);
219+
220+
frame->type = FRAME_TYPE_MANAGED_TO_NATIVE;
221+
222+
ji = mini_jit_info_table_find ((gpointer)(*lmf)->pc);
223+
if (!ji)
224+
return FALSE;
225+
226+
memcpy (&new_ctx->gregs, (*lmf)->gregs, sizeof (host_mgreg_t) * RISCV_N_GREGS);
227+
new_ctx->gregs [0] = (*lmf)->pc; // use [0] as pc reg since x0 is hard-wired zero
228+
229+
/* we substract 1, so that the IP points into the call instruction */
230+
new_ctx->gregs [0]--;
231+
232+
*lmf = (MonoLMF *)(((gsize)(*lmf)->previous_lmf) & ~(TARGET_SIZEOF_VOID_P - 1));
233+
234+
return TRUE;
210235
}
211236

212237
return FALSE;

0 commit comments

Comments
 (0)