#include "mini-amd64.h"
#include "debugger-agent.h"
+#ifdef ENABLE_INTERPRETER
+#include "interp/interp.h"
+#endif
+
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
#define IS_REX(inst) (((inst) >= 0x40) && ((inst) <= 0x4f))
/*
* mono_arch_get_enter_icall_trampoline:
*
- * A trampoline that handles the transition from interpreter into native world.
- * It requiers to set up a descriptor (MethodArguments) that describes the
- * required arguments passed to the callee.
+ * A trampoline that handles the transition from interpreter into native
+ * world. It requiers to set up a descriptor (InterpMethodArguments), so the
+ * trampoline can translate the arguments into the native calling convention.
+ *
+ * See also `build_args_from_sig ()` in interp.c.
*/
gpointer
mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
{
#ifdef ENABLE_INTERPRETER
- const int gregs_num = 12;
- const int fregs_num = 3;
+ const int gregs_num = INTERP_ICALL_TRAMP_IARGS;
+ const int fregs_num = INTERP_ICALL_TRAMP_FARGS;
guint8 *start = NULL, *code, *label_gexits [gregs_num], *label_fexits [fregs_num], *label_leave_tramp [3], *label_is_float_ret;
MonoJumpInfo *ji = NULL;
GSList *unwind_ops = NULL;
amd64_mov_reg_reg (code, AMD64_RBP, AMD64_RSP, sizeof (mgreg_t));
amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, ALIGN_TO (framesize, MONO_ARCH_FRAME_ALIGNMENT));
- /* save MethodArguments* onto stack */
+ /* save InterpMethodArguments* onto stack */
amd64_mov_membase_reg (code, AMD64_RBP, off_methodargs, AMD64_ARG_REG2, sizeof (mgreg_t));
/* save target address on stack */
amd64_mov_membase_reg (code, AMD64_RBP, off_targetaddr, AMD64_ARG_REG1, sizeof (mgreg_t));
- /* load pointer to MethodArguments* into R11 */
+ /* load pointer to InterpMethodArguments* into R11 */
amd64_mov_reg_reg (code, AMD64_R11, AMD64_ARG_REG2, 8);
- /* move flen into RAX */ // TODO: struct offset
- amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, 16, sizeof (mgreg_t));
- /* load pointer to fregs into R11 */ // TODO: struct offset
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 24, sizeof (mgreg_t));
+ /* move flen into RAX */
+ amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, flen), sizeof (mgreg_t));
+ /* load pointer to fargs into R11 */
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, fargs), sizeof (mgreg_t));
for (i = 0; i < fregs_num; ++i) {
amd64_test_reg_reg (code, AMD64_RAX, AMD64_RAX);
for (i = 0; i < fregs_num; i++)
x86_patch (label_fexits [i], code);
- /* load pointer to MethodArguments* into R11 */
+ /* load pointer to InterpMethodArguments* into R11 */
amd64_mov_reg_reg (code, AMD64_R11, AMD64_ARG_REG2, sizeof (mgreg_t));
- /* move ilen into RAX */ // TODO: struct offset
- amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, 0, sizeof (mgreg_t));
+ /* move ilen into RAX */
+ amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, ilen), sizeof (mgreg_t));
int stack_offset = 0;
for (i = 0; i < gregs_num; i++) {
label_gexits [i] = code;
x86_branch32 (code, X86_CC_Z, 0, FALSE);
- /* load pointer to MethodArguments* into R11 */
+ /* load pointer to InterpMethodArguments* into R11 */
amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, off_methodargs, sizeof (mgreg_t));
- /* load pointer to iregs into R11 */ // TODO: struct offset
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 8, sizeof (mgreg_t));
+ /* load pointer to iargs into R11 */
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, iargs), sizeof (mgreg_t));
if (i < PARAM_REGS) {
amd64_mov_reg_membase (code, param_regs [i], AMD64_R11, i * sizeof (mgreg_t), sizeof (mgreg_t));
/* call into native function */
amd64_call_reg (code, AMD64_R11);
- /* load MethodArguments */
+ /* load InterpMethodArguments */
amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, off_methodargs, sizeof (mgreg_t));
- /* load is_float_ret */ // TODO: struct offset
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0x28, sizeof (mgreg_t));
+ /* load is_float_ret */
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, is_float_ret), sizeof (mgreg_t));
/* check if a float return value is expected */
amd64_test_reg_reg (code, AMD64_R11, AMD64_R11);
x86_branch8 (code, X86_CC_NZ, 0, FALSE);
/* greg return */
- /* load MethodArguments */
+ /* load InterpMethodArguments */
amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, off_methodargs, sizeof (mgreg_t));
- /* load retval */ // TODO: struct offset
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0x20, sizeof (mgreg_t));
+ /* load retval */
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, retval), sizeof (mgreg_t));
amd64_test_reg_reg (code, AMD64_R11, AMD64_R11);
label_leave_tramp [0] = code;
/* freg return */
x86_patch (label_is_float_ret, code);
- /* load MethodArguments */
+ /* load InterpMethodArguments */
amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, off_methodargs, sizeof (mgreg_t));
- /* load retval */ // TODO: struct offset
- amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0x20, sizeof (mgreg_t));
+ /* load retval */
+ amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, MONO_STRUCT_OFFSET (InterpMethodArguments, retval), sizeof (mgreg_t));
amd64_test_reg_reg (code, AMD64_R11, AMD64_R11);
label_leave_tramp [2] = code;
#include <mono/arch/arm64/arm64-codegen.h>
#include <mono/metadata/abi-details.h>
+#ifdef ENABLE_INTERPRETER
+#include "interp/interp.h"
+#endif
+
+
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
void
mono_arch_get_enter_icall_trampoline (MonoTrampInfo **info)
{
#ifdef ENABLE_INTERPRETER
- /* sync with constants in interp.c */
- /* TODO: should be shared with other platforms */
- const int gregs_num = ARMREG_R12;
- const int fregs_num = 3;
+ const int gregs_num = INTERP_ICALL_TRAMP_IARGS;
+ const int fregs_num = INTERP_ICALL_TRAMP_FARGS;
guint8 *start = NULL, *code, *label_gexits [gregs_num], *label_fexits [fregs_num], *label_leave_tramp [3], *label_is_float_ret;
MonoJumpInfo *ji = NULL;
arm_stpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, stack_space);
arm_addx_imm (code, ARMREG_FP, ARMREG_SP, stack_space);
- /* save MethodArguments* onto stack */
+ /* save InterpMethodArguments* onto stack */
arm_strx (code, ARMREG_R1, ARMREG_FP, off_methodargs);
/* save target address onto stack */
arm_strx (code, ARMREG_R0, ARMREG_FP, off_targetaddr);
- /* load pointer to MethodArguments* into IP0 */
+ /* load pointer to InterpMethodArguments* into IP0 */
arm_movx (code, ARMREG_IP0, ARMREG_R1);
- /* move flen into R9 */ // TODO: struct offset
- arm_ldrx (code, ARMREG_R9, ARMREG_IP0, 16);
- /* load pointer to fregs into R10 */ // TODO: struct offset
- arm_ldrx (code, ARMREG_R10, ARMREG_IP0, 24);
+ /* move flen into R9 */
+ arm_ldrx (code, ARMREG_R9, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, flen));
+ /* load pointer to fargs into R10 */
+ arm_ldrx (code, ARMREG_R10, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, fargs));
for (i = 0; i < fregs_num; ++i) {
arm_cmpx_imm (code, ARMREG_R9, 0);
label_fexits [i] = code;
arm_bcc (code, ARMCOND_EQ, 0);
+ g_assert (i <= ARMREG_D7); /* otherwise, need to pass args on stack */
arm_ldrfpx (code, i, ARMREG_R10, i * sizeof (double));
arm_subx_imm (code, ARMREG_R9, ARMREG_R9, 1);
}
for (i = 0; i < fregs_num; i++)
mono_arm_patch (label_fexits [i], code, MONO_R_ARM64_BCC);
- /* move ilen into R9 */ // TODO: struct offset
- arm_ldrx (code, ARMREG_R9, ARMREG_IP0, 0);
- /* load pointer to iregs into R10 */ // TODO: struct offset
- arm_ldrx (code, ARMREG_R10, ARMREG_IP0, 8);
+ /* move ilen into R9 */
+ arm_ldrx (code, ARMREG_R9, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, ilen));
+ /* load pointer to iargs into R10 */
+ arm_ldrx (code, ARMREG_R10, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, iargs));
int stack_offset = 0;
for (i = 0; i < gregs_num; i++) {
/* call into native function */
arm_blrx (code, ARMREG_R11);
- /* load MethodArguments */
+ /* load InterpMethodArguments */
arm_ldrx (code, ARMREG_IP0, ARMREG_FP, off_methodargs);
- /* load is_float_ret */ // TODO: struct offset
- arm_ldrx (code, ARMREG_R11, ARMREG_IP0, 0x28);
+ /* load is_float_ret */
+ arm_ldrx (code, ARMREG_R11, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, is_float_ret));
/* check if a float return value is expected */
arm_cmpx_imm (code, ARMREG_R11, 0);
arm_bcc (code, ARMCOND_NE, 0);
/* greg return */
- /* load retval */ // TODO: struct offset
- arm_ldrx (code, ARMREG_R11, ARMREG_IP0, 0x20);
+ /* load retval */
+ arm_ldrx (code, ARMREG_R11, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, retval));
arm_cmpx_imm (code, ARMREG_R11, 0);
label_leave_tramp [0] = code;
/* freg return */
mono_arm_patch (label_is_float_ret, code, MONO_R_ARM64_BCC);
- /* load retval */ // TODO: struct offset
- arm_ldrx (code, ARMREG_R11, ARMREG_IP0, 0x20);
+ /* load retval */
+ arm_ldrx (code, ARMREG_R11, ARMREG_IP0, MONO_STRUCT_OFFSET (InterpMethodArguments, retval));
arm_cmpx_imm (code, ARMREG_R11, 0);
label_leave_tramp [2] = code;