X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Ftramp-arm.c;h=bb500a7c0f505c954834f36b68c97deb7a424337;hb=fd12271ce38cea612b0fa3161af9b725ceeb904a;hp=225ef9f4e7cb10e2ad870b7c7728a11b39d72557;hpb=9bcda222deab87fd9deb869da5d94f7fe596c7c2;p=mono.git diff --git a/mono/mini/tramp-arm.c b/mono/mini/tramp-arm.c index 225ef9f4e7c..bb500a7c0f5 100644 --- a/mono/mini/tramp-arm.c +++ b/mono/mini/tramp-arm.c @@ -12,10 +12,12 @@ #include #include +#include #include #include #include #include +#include #include "mini.h" #include "mini-arm.h" @@ -131,12 +133,6 @@ mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs) mono_arch_patch_callsite (NULL, code, mini_get_nullified_class_init_trampoline ()); } -void -mono_arch_nullify_plt_entry (guint8 *code, mgreg_t *regs) -{ - mono_arch_patch_plt_entry (code, NULL, regs, mini_get_nullified_class_init_trampoline ()); -} - #ifndef DISABLE_JIT #define arm_is_imm12(v) ((int)(v) > -4096 && (int)(v) < 4096) @@ -173,7 +169,7 @@ emit_bx (guint8* code, int reg) return code; } -/* Stack size for trampoline function +/* Stack size for trampoline function */ #define STACK ALIGN_TO (sizeof (MonoLMF), 8) @@ -195,7 +191,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf gpointer *constants; #endif - int cfa_offset, lmf_offset, regsave_size, lr_offset; + int cfa_offset, regsave_size, lr_offset; GSList *unwind_ops = NULL; MonoJumpInfo *ji = NULL; int buf_len; @@ -207,7 +203,12 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf /* Now we'll create in 'buf' the ARM trampoline code. This is the trampoline code common to all methods */ - buf_len = 212; + buf_len = 272; + + /* Add space for saving/restoring VFP regs. */ + if (mono_arm_is_hard_float ()) + buf_len += 8 * 2; + code = buf = mono_global_codeman_reserve (buf_len); /* @@ -216,8 +217,6 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf * saved as sp + LR_OFFSET by the push in the specific trampoline */ - /* The offset of lmf inside the stack frame */ - lmf_offset = STACK - sizeof (MonoLMF); /* The size of the area already allocated by the push in the specific trampoline */ regsave_size = 14 * sizeof (mgreg_t); /* The offset where lr was saved inside the regsave area */ @@ -282,11 +281,13 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf * The pointer to the struct is put in r1. * the iregs array is already allocated on the stack by push. */ - ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, STACK - regsave_size); + code = mono_arm_emit_load_imm (code, ARMREG_R2, STACK - regsave_size); + ARM_SUB_REG_REG (code, ARMREG_SP, ARMREG_SP, ARMREG_R2); cfa_offset += STACK - regsave_size; mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset); /* V1 == lmf */ - ARM_ADD_REG_IMM8 (code, ARMREG_V1, ARMREG_SP, STACK - sizeof (MonoLMF)); + code = mono_arm_emit_load_imm (code, ARMREG_R2, STACK - sizeof (MonoLMF)); + ARM_ADD_REG_REG (code, ARMREG_V1, ARMREG_SP, ARMREG_R2); /* * The stack now looks like: @@ -296,38 +297,50 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf */ /* r0 is the result from mono_get_lmf_addr () */ - ARM_STR_IMM (code, ARMREG_R0, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, lmf_addr)); + ARM_STR_IMM (code, ARMREG_R0, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, lmf_addr)); /* new_lmf->previous_lmf = *lmf_addr */ - ARM_LDR_IMM (code, ARMREG_R2, ARMREG_R0, G_STRUCT_OFFSET (MonoLMF, previous_lmf)); - ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, previous_lmf)); + ARM_LDR_IMM (code, ARMREG_R2, ARMREG_R0, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf)); + ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf)); /* *(lmf_addr) = r1 */ - ARM_STR_IMM (code, ARMREG_V1, ARMREG_R0, G_STRUCT_OFFSET (MonoLMF, previous_lmf)); + ARM_STR_IMM (code, ARMREG_V1, ARMREG_R0, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf)); /* save method info (it's in v2) */ if ((tramp_type == MONO_TRAMPOLINE_JIT) || (tramp_type == MONO_TRAMPOLINE_JUMP)) - ARM_STR_IMM (code, ARMREG_V2, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, method)); + ARM_STR_IMM (code, ARMREG_V2, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, method)); else { ARM_MOV_REG_IMM8 (code, ARMREG_R2, 0); - ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, method)); + ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, method)); } /* save caller SP */ - ARM_ADD_REG_IMM8 (code, ARMREG_R2, ARMREG_SP, cfa_offset); - ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, sp)); + code = mono_arm_emit_load_imm (code, ARMREG_R2, cfa_offset); + ARM_ADD_REG_REG (code, ARMREG_R2, ARMREG_SP, ARMREG_R2); + ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, sp)); /* save caller FP */ - ARM_LDR_IMM (code, ARMREG_R2, ARMREG_V1, (G_STRUCT_OFFSET (MonoLMF, iregs) + ARMREG_FP*4)); - ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, fp)); + ARM_LDR_IMM (code, ARMREG_R2, ARMREG_V1, (MONO_STRUCT_OFFSET (MonoLMF, iregs) + ARMREG_FP*4)); + ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, fp)); /* save the IP (caller ip) */ if (tramp_type == MONO_TRAMPOLINE_JUMP) { ARM_MOV_REG_IMM8 (code, ARMREG_R2, 0); } else { - ARM_LDR_IMM (code, ARMREG_R2, ARMREG_V1, (G_STRUCT_OFFSET (MonoLMF, iregs) + 13*4)); + ARM_LDR_IMM (code, ARMREG_R2, ARMREG_V1, (MONO_STRUCT_OFFSET (MonoLMF, iregs) + 13*4)); + } + ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, ip)); + + /* Save VFP registers. */ + if (mono_arm_is_hard_float ()) { + /* + * Strictly speaking, we don't have to save d0-d7 in the LMF, but + * it's easier than attempting to store them on the stack since + * this trampoline code is pretty messy. + */ + ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, fregs)); + ARM_FSTMD (code, ARM_VFP_D0, 8, ARMREG_R0); } - ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, ip)); /* * Now we're ready to call xxx_trampoline (). */ /* Arg 1: the saved registers */ - ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, iregs)); + ARM_ADD_REG_IMM (code, ARMREG_R0, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, iregs), 0); /* Arg 2: code (next address to the instruction that called us) */ if (tramp_type == MONO_TRAMPOLINE_JUMP) { @@ -366,7 +379,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf * clobbered). This way we can just restore all the regs in one inst * and branch to IP. */ - ARM_STR_IMM (code, ARMREG_R0, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, iregs) + (ARMREG_R12 * sizeof (mgreg_t))); + ARM_STR_IMM (code, ARMREG_R0, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, iregs) + (ARMREG_R12 * sizeof (mgreg_t))); /* Check for thread interruption */ /* This is not perf critical code so no need to check the interrupt flag */ @@ -401,11 +414,17 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf * the same state as before we executed. */ /* ip = previous_lmf */ - ARM_LDR_IMM (code, ARMREG_IP, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, previous_lmf)); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf)); /* lr = lmf_addr */ - ARM_LDR_IMM (code, ARMREG_LR, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, lmf_addr)); + ARM_LDR_IMM (code, ARMREG_LR, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, lmf_addr)); /* *(lmf_addr) = previous_lmf */ - ARM_STR_IMM (code, ARMREG_IP, ARMREG_LR, G_STRUCT_OFFSET (MonoLMF, previous_lmf)); + ARM_STR_IMM (code, ARMREG_IP, ARMREG_LR, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf)); + + /* Restore VFP registers. */ + if (mono_arm_is_hard_float ()) { + ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_V1, MONO_STRUCT_OFFSET (MonoLMF, fregs)); + ARM_FLDMD (code, ARM_VFP_D0, 8, ARMREG_R0); + } /* Non-standard function epilogue. Instead of doing a proper * return, we just jump to the compiled code. @@ -685,8 +704,8 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info ARM_MOV_REG_REG (code, ARMREG_R1, ARMREG_R0); } else { /* load rgctx ptr from vtable */ - g_assert (arm_is_imm12 (G_STRUCT_OFFSET (MonoVTable, runtime_generic_context))); - ARM_LDR_IMM (code, ARMREG_R1, ARMREG_R0, G_STRUCT_OFFSET (MonoVTable, runtime_generic_context)); + g_assert (arm_is_imm12 (MONO_STRUCT_OFFSET (MonoVTable, runtime_generic_context))); + ARM_LDR_IMM (code, ARMREG_R1, ARMREG_R0, MONO_STRUCT_OFFSET (MonoVTable, runtime_generic_context)); /* is the rgctx ptr null? */ ARM_CMP_REG_IMM (code, ARMREG_R1, 0, 0); /* if yes, jump to actual trampoline */ @@ -1053,7 +1072,7 @@ mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpoint #endif -#if defined(MONOTOUCH) || defined(MONO_EXTENSIONS) +#if defined(ENABLE_GSHAREDVT) #include "../../../mono-extensions/mono/mini/tramp-arm-gsharedvt.c"