{
mono_aot_register_jit_icall ("mono_arm_throw_exception", mono_arm_throw_exception);
mono_aot_register_jit_icall ("mono_arm_resume_unwind", mono_arm_resume_unwind);
- mono_aot_register_jit_icall ("mono_arm_handler_block_trampoline_helper", mono_arm_handler_block_trampoline_helper);
if (!mono_aot_only)
bp_trampoline = mini_get_breakpoint_trampoline ();
{
int i;
- if (sig->hasthis + sig->param_count > PARAM_REGS + DYN_CALL_STACK_ARGS)
- return FALSE;
-
// FIXME: Add more cases
switch (cinfo->ret.storage) {
case ArgNone:
case ArgInFRegR4:
case ArgHFA:
case ArgVtypeByRef:
- break;
case ArgOnStack:
- if (ainfo->offset >= DYN_CALL_STACK_ARGS * sizeof (mgreg_t))
- return FALSE;
break;
default:
return FALSE;
g_free (ainfo);
}
+int
+mono_arch_dyn_call_get_buf_size (MonoDynCallInfo *info)
+{
+ ArchDynCallInfo *ainfo = (ArchDynCallInfo*)info;
+
+ g_assert (ainfo->cinfo->stack_usage % MONO_ARCH_FRAME_ALIGNMENT == 0);
+ return sizeof (DynCallArgs) + ainfo->cinfo->stack_usage;
+}
+
static double
bitcast_r4_to_r8 (float f)
{
}
void
-mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, guint8 *buf, int buf_len)
+mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, guint8 *buf)
{
ArchDynCallInfo *dinfo = (ArchDynCallInfo*)info;
DynCallArgs *p = (DynCallArgs*)buf;
CallInfo *cinfo = dinfo->cinfo;
int buffer_offset = 0;
- g_assert (buf_len >= sizeof (DynCallArgs));
-
p->res = 0;
p->ret = ret;
p->n_fpargs = dinfo->n_fpargs;
p->n_fpret = dinfo->n_fpret;
+ p->n_stackargs = cinfo->stack_usage / sizeof (mgreg_t);
arg_index = 0;
greg = 0;
code = emit_ldrfpx (code, ARMREG_D0 + i, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, fpregs) + (i * 8));
arm_patch_rel (labels [0], code, MONO_R_ARM64_BCC);
+ /* Allocate callee area */
+ code = emit_ldrx (code, ARMREG_R0, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, n_stackargs));
+ arm_lslw (code, ARMREG_R0, ARMREG_R0, 3);
+ arm_movspx (code, ARMREG_R1, ARMREG_SP);
+ arm_subx (code, ARMREG_R1, ARMREG_R1, ARMREG_R0);
+ arm_movspx (code, ARMREG_SP, ARMREG_R1);
+
/* Set stack args */
- for (i = 0; i < DYN_CALL_STACK_ARGS; ++i) {
- code = emit_ldrx (code, ARMREG_R0, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, regs) + ((PARAM_REGS + 1 + i) * sizeof (mgreg_t)));
- code = emit_strx (code, ARMREG_R0, ARMREG_SP, i * sizeof (mgreg_t));
- }
+ /* R1 = limit */
+ code = emit_ldrx (code, ARMREG_R1, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, n_stackargs));
+ /* R2 = pointer into 'regs' */
+ code = emit_imm (code, ARMREG_R2, MONO_STRUCT_OFFSET (DynCallArgs, regs) + ((PARAM_REGS + 1) * sizeof (mgreg_t)));
+ arm_addx (code, ARMREG_R2, ARMREG_LR, ARMREG_R2);
+ /* R3 = pointer to stack */
+ arm_movspx (code, ARMREG_R3, ARMREG_SP);
+ labels [0] = code;
+ arm_b (code, code);
+ labels [1] = code;
+ code = emit_ldrx (code, ARMREG_R5, ARMREG_R2, 0);
+ code = emit_strx (code, ARMREG_R5, ARMREG_R3, 0);
+ code = emit_addx_imm (code, ARMREG_R2, ARMREG_R2, sizeof (mgreg_t));
+ code = emit_addx_imm (code, ARMREG_R3, ARMREG_R3, sizeof (mgreg_t));
+ code = emit_subx_imm (code, ARMREG_R1, ARMREG_R1, 1);
+ arm_patch_rel (labels [0], code, MONO_R_ARM64_B);
+ arm_cmpw (code, ARMREG_R1, ARMREG_RZR);
+ arm_bcc (code, ARMCOND_GT, labels [1]);
/* Set argument registers + r8 */
- code = mono_arm_emit_load_regarray (code, 0x1ff, ARMREG_LR, 0);
+ code = mono_arm_emit_load_regarray (code, 0x1ff, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, regs));
/* Make the call */
arm_blrx (code, ARMREG_IP1);
#endif
break;
}
-
+ case OP_FILL_PROF_CALL_CTX:
+ for (int i = 0; i < MONO_MAX_IREGS; i++)
+ if ((MONO_ARCH_CALLEE_SAVED_REGS & (1 << i)) || i == ARMREG_SP || i == ARMREG_FP)
+ arm_strx (code, i, ins->sreg1, MONO_STRUCT_OFFSET (MonoContext, regs) + i * sizeof (mgreg_t));
+ break;
default:
g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
g_assert_not_reached ();
return NULL;
}
-gboolean
-mono_arch_print_tree (MonoInst *tree, int arity)
-{
- return FALSE;
-}
-
guint32
mono_arch_get_patch_offset (guint8 *code)
{
return get_call_info (mp, sig);
}
-gpointer
-mono_arch_install_handler_block_guard (MonoJitInfo *ji, MonoJitExceptionInfo *clause, MonoContext *ctx, gpointer new_value)
-{
- gpointer *lr_loc;
- char *old_value;
- char *bp;
-
- /*Load the spvar*/
- bp = MONO_CONTEXT_GET_BP (ctx);
- lr_loc = (gpointer*)(bp + clause->exvar_offset);
-
- old_value = *lr_loc;
- if ((char*)old_value < (char*)ji->code_start || (char*)old_value > ((char*)ji->code_start + ji->code_size))
- return old_value;
-
- *lr_loc = new_value;
-
- return old_value;
-}