Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/mono/mono/arch/riscv/riscv-codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,20 @@ enum {
((funct5) << 27)); \
} while (0)

static G_GNUC_UNUSED inline gboolean
riscv_is_jal_disp (void *code, void *target)
{
gint64 disp = ((char *)(target) - (char *)(code)) / 2;

return (disp > -(1 << 19)) && (disp < (1 << 19));
}

static G_GNUC_UNUSED inline gsize
riscv_get_jal_disp (void *code, void *target)
{
return ((char *)(target) - (char *)(code)) & 0xfffffffe;
}

/*
* NOTE: When you add new codegen macros or change existing ones, you must
* expand riscv-codegen-test.c to cover them, and update riscv-codegen.exp32
Expand Down
43 changes: 34 additions & 9 deletions src/mono/mono/mini/exceptions-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ mono_arch_exceptions_init (void)
// NOT_IMPLEMENTED;
}

/*
* mono_arch_unwind_frame:
*
* This function is used to gather information from @ctx, and store it in @frame_info.
* It unwinds one stack frame, and stores the resulting context into @new_ctx. @lmf
* is modified if needed.
* Returns TRUE on success, FALSE otherwise.
*/
gboolean
mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji,
MonoContext *ctx, MonoContext *new_ctx, MonoLMF **lmf,
Expand All @@ -160,7 +168,7 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji,
*new_ctx = *ctx;

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

gboolean success = mono_unwind_frame (unwind_info, unwind_info_len, (guint8*)ji->code_start,
(guint8*)ji->code_start + ji->code_size,
(guint8*)ip, NULL, regs, MONO_MAX_IREGS + 8,
save_locations, MONO_MAX_IREGS, (guint8**)&cfa);
gboolean success = mono_unwind_frame (unwind_info, unwind_info_len, (guint8 *)ji->code_start,
(guint8 *)ji->code_start + ji->code_size, (guint8 *)ip, NULL, regs,
MONO_MAX_IREGS + 12 + 1, save_locations, MONO_MAX_IREGS, (guint8 **)&cfa);

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

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

if (*lmf)
NOT_IMPLEMENTED;
if (*lmf && (*lmf)->gregs [RISCV_FP] && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->gregs [RISCV_SP])) {
/* remove any unused lmf */
*lmf = (MonoLMF *)(((gsize)(*lmf)->previous_lmf) & ~(TARGET_SIZEOF_VOID_P - 1));
}

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

return TRUE;
} else if (*lmf) {
NOT_IMPLEMENTED;
g_assert ((((guint64)(*lmf)->previous_lmf) & 2) == 0);

frame->type = FRAME_TYPE_MANAGED_TO_NATIVE;

ji = mini_jit_info_table_find ((gpointer)(*lmf)->pc);
if (!ji)
return FALSE;

memcpy (&new_ctx->gregs, (*lmf)->gregs, sizeof (host_mgreg_t) * RISCV_N_GREGS);
new_ctx->gregs [0] = (*lmf)->pc; // use [0] as pc reg since x0 is hard-wired zero

/* we substract 1, so that the IP points into the call instruction */
new_ctx->gregs [0]--;

*lmf = (MonoLMF *)(((gsize)(*lmf)->previous_lmf) & ~(TARGET_SIZEOF_VOID_P - 1));

return TRUE;
}

return FALSE;
Expand Down
Loading