X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-arm.c;h=cfbbd02cec19520d411d9e7a7a31face0b72f112;hb=dbaca79c4797350ac59026278561e325a86b7a40;hp=13a3ffee37f8159a3b1346bf99c09b007ab5159b;hpb=f240b04af666162e3f42cc4198cdf7dc02cdadd9;p=mono.git diff --git a/mono/mini/mini-arm.c b/mono/mini/mini-arm.c index 13a3ffee37f..cfbbd02cec1 100644 --- a/mono/mini/mini-arm.c +++ b/mono/mini/mini-arm.c @@ -23,7 +23,6 @@ #include #include "mini-arm.h" -#include "mini-arm-tls.h" #include "cpu-arm.h" #include "trace.h" #include "ir-emit.h" @@ -31,12 +30,6 @@ #include "mini-gc.h" #include "mono/arch/arm/arm-vfp-codegen.h" -#if (defined(HAVE_KW_THREAD) && defined(__linux__) && defined(__ARM_EABI__)) \ - || defined(TARGET_ANDROID) \ - || (defined(TARGET_IOS) && !defined(TARGET_WATCHOS)) -#define HAVE_FAST_TLS -#endif - /* Sanity check: This makes no sense */ #if defined(ARM_FPU_NONE) && (defined(ARM_FPU_VFP) || defined(ARM_FPU_VFP_HARD)) #error "ARM_FPU_NONE is defined while one of ARM_FPU_VFP/ARM_FPU_VFP_HARD is defined" @@ -329,100 +322,53 @@ mono_arm_patchable_bl (guint8 *code, int cond) return code; } -static guint8* -mono_arm_emit_tls_get (MonoCompile *cfg, guint8* code, int dreg, int tls_offset) -{ -#ifdef HAVE_FAST_TLS - code = mono_arm_emit_load_imm (code, ARMREG_R0, tls_offset); - if (cfg->compile_aot) { - /* - * This opcode is generated by CEE_MONO_JIT_ATTACH, so it can execute on - * threads which are not yet attached to the runtime. This means we can't - * call it directly, since the call would go through the trampoline code - * which assumes the thread is attached. So use a separate patch info type - * for it, and load it from a preinitialized GOT slot. - */ - code = emit_aotconst (cfg, code, ARMREG_R1, MONO_PATCH_INFO_GET_TLS_TRAMP, NULL); - code = emit_call_reg (code, ARMREG_R1); - } else { - mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, - "mono_get_tls_key"); - code = emit_call_seq (cfg, code); - } - if (dreg != ARMREG_R0) - ARM_MOV_REG_REG (code, dreg, ARMREG_R0); -#else - g_assert_not_reached (); +#if defined(__ARM_EABI__) && defined(__linux__) && !defined(PLATFORM_ANDROID) && !defined(__native_client__) +#define HAVE_AEABI_READ_TP 1 #endif - return code; -} -static guint8* -mono_arm_emit_tls_get_reg (MonoCompile *cfg, guint8* code, int dreg, int tls_offset_reg) +#ifdef HAVE_AEABI_READ_TP +gpointer __aeabi_read_tp (void); +#endif + +gboolean +mono_arch_have_fast_tls (void) { -#ifdef HAVE_FAST_TLS - if (tls_offset_reg != ARMREG_R0) - ARM_MOV_REG_REG (code, ARMREG_R0, tls_offset_reg); - if (cfg->compile_aot) { - code = emit_aotconst (cfg, code, ARMREG_R1, MONO_PATCH_INFO_GET_TLS_TRAMP, NULL); - code = emit_call_reg (code, ARMREG_R1); - } else { - mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, - "mono_get_tls_key"); - code = emit_call_seq (cfg, code); - } - if (dreg != ARMREG_R0) - ARM_MOV_REG_REG (code, dreg, ARMREG_R0); +#ifdef HAVE_AEABI_READ_TP + static gboolean have_fast_tls = FALSE; + static gboolean inited = FALSE; + gpointer tp1, tp2; + + if (mini_get_debug_options ()->use_fallback_tls) + return FALSE; + + if (inited) + return have_fast_tls; + + tp1 = __aeabi_read_tp (); + asm volatile("mrc p15, 0, %0, c13, c0, 3" : "=r" (tp2)); + + have_fast_tls = tp1 && tp1 == tp2; + inited = TRUE; + return have_fast_tls; #else - g_assert_not_reached (); + return FALSE; #endif - return code; } static guint8* -mono_arm_emit_tls_set (MonoCompile *cfg, guint8* code, int sreg, int tls_offset) +emit_tls_get (guint8 *code, int dreg, int tls_offset) { -#ifdef HAVE_FAST_TLS - if (sreg != ARMREG_R1) - ARM_MOV_REG_REG (code, ARMREG_R1, sreg); - code = mono_arm_emit_load_imm (code, ARMREG_R0, tls_offset); - mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, - "mono_set_tls_key"); - code = emit_call_seq (cfg, code); -#else - g_assert_not_reached (); -#endif + ARM_MRC (code, 15, 0, dreg, 13, 0, 3); + ARM_LDR_IMM (code, dreg, dreg, tls_offset); return code; } static guint8* -mono_arm_emit_tls_set_reg (MonoCompile *cfg, guint8* code, int sreg, int tls_offset_reg) +emit_tls_set (guint8 *code, int sreg, int tls_offset) { -#ifdef HAVE_FAST_TLS - /* Get sreg in R1 and tls_offset_reg in R0 */ - if (tls_offset_reg == ARMREG_R1) { - if (sreg == ARMREG_R0) { - /* swap sreg and tls_offset_reg */ - ARM_EOR_REG_REG (code, sreg, sreg, tls_offset_reg); - ARM_EOR_REG_REG (code, tls_offset_reg, sreg, tls_offset_reg); - ARM_EOR_REG_REG (code, sreg, sreg, tls_offset_reg); - } else { - ARM_MOV_REG_REG (code, ARMREG_R0, tls_offset_reg); - if (sreg != ARMREG_R1) - ARM_MOV_REG_REG (code, ARMREG_R1, sreg); - } - } else { - if (sreg != ARMREG_R1) - ARM_MOV_REG_REG (code, ARMREG_R1, sreg); - if (tls_offset_reg != ARMREG_R0) - ARM_MOV_REG_REG (code, ARMREG_R0, tls_offset_reg); - } - mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, - "mono_set_tls_key"); - code = emit_call_seq (cfg, code); -#else - g_assert_not_reached (); -#endif + int tp_reg = (sreg != ARMREG_R0) ? ARMREG_R0 : ARMREG_R1; + ARM_MRC (code, 15, 0, tp_reg, 13, 0, 3); + ARM_STR_IMM (code, sreg, tp_reg, tls_offset); return code; } @@ -435,31 +381,13 @@ mono_arm_emit_tls_set_reg (MonoCompile *cfg, guint8* code, int sreg, int tls_off static guint8* emit_save_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset) { - gboolean get_lmf_fast = FALSE; int i; - if (mono_arm_have_tls_get ()) { - get_lmf_fast = TRUE; - if (cfg->compile_aot) { - /* OP_AOTCONST */ - mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_TLS_OFFSET, (gpointer)TLS_KEY_LMF_ADDR); - ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0); - ARM_B (code, 0); - *(gpointer*)code = NULL; - code += 4; - /* Load the value from the GOT */ - ARM_LDR_REG_REG (code, ARMREG_R1, ARMREG_PC, ARMREG_R1); - code = mono_arm_emit_tls_get_reg (cfg, code, ARMREG_R0, ARMREG_R1); - } else { - gint32 lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset (); - g_assert (lmf_addr_tls_offset != -1); - code = mono_arm_emit_tls_get (cfg, code, ARMREG_R0, lmf_addr_tls_offset); - } - } - - if (!get_lmf_fast) { - mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, - (gpointer)"mono_get_lmf_addr"); + if (mono_arch_have_fast_tls () && mono_tls_get_tls_offset (TLS_KEY_LMF_ADDR) != -1) { + code = emit_tls_get (code, ARMREG_R0, mono_tls_get_tls_offset (TLS_KEY_LMF_ADDR)); + } else { + mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, + (gpointer)"mono_tls_get_lmf_addr"); code = emit_call_seq (cfg, code); } /* we build the MonoLMF structure on the stack - see mini-arm.h */ @@ -602,22 +530,6 @@ emit_restore_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset) #endif /* #ifndef DISABLE_JIT */ -/* - * mono_arm_have_tls_get: - * - * Returns whether we have tls access implemented on the current - * platform - */ -gboolean -mono_arm_have_tls_get (void) -{ -#ifdef HAVE_FAST_TLS - return TRUE; -#else - return FALSE; -#endif -} - /* * mono_arch_get_argument_info: * @csig: a method signature @@ -4286,16 +4198,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } break; case OP_TLS_GET: - code = mono_arm_emit_tls_get (cfg, code, ins->dreg, ins->inst_offset); - break; - case OP_TLS_GET_REG: - code = mono_arm_emit_tls_get_reg (cfg, code, ins->dreg, ins->sreg1); + code = emit_tls_get (code, ins->dreg, ins->inst_offset); break; case OP_TLS_SET: - code = mono_arm_emit_tls_set (cfg, code, ins->sreg1, ins->inst_offset); - break; - case OP_TLS_SET_REG: - code = mono_arm_emit_tls_set_reg (cfg, code, ins->sreg1, ins->sreg2); + code = emit_tls_set (code, ins->sreg1, ins->inst_offset); break; case OP_ATOMIC_EXCHANGE_I4: case OP_ATOMIC_CAS_I4: @@ -5153,19 +5059,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; } case OP_GENERIC_CLASS_INIT: { - static int byte_offset = -1; - static guint8 bitmask; - guint32 imm8; + int byte_offset; guint8 *jump; - if (byte_offset < 0) - mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask); + byte_offset = MONO_STRUCT_OFFSET (MonoVTable, initialized); g_assert (arm_is_imm8 (byte_offset)); ARM_LDRSB_IMM (code, ARMREG_IP, ins->sreg1, byte_offset); - imm8 = mono_arm_is_rotated_imm8 (bitmask, &rot_amount); - g_assert (imm8 >= 0); - ARM_AND_REG_IMM (code, ARMREG_IP, ARMREG_IP, imm8, rot_amount); ARM_CMP_REG_IMM (code, ARMREG_IP, 0, 0); jump = code; ARM_B_COND (code, ARMCOND_NE, 0); @@ -6002,40 +5902,6 @@ mono_arch_register_lowlevel_calls (void) mono_register_jit_icall (mono_arm_throw_exception, "mono_arm_throw_exception", mono_create_icall_signature ("void"), TRUE); mono_register_jit_icall (mono_arm_throw_exception_by_token, "mono_arm_throw_exception_by_token", mono_create_icall_signature ("void"), TRUE); mono_register_jit_icall (mono_arm_unaligned_stack, "mono_arm_unaligned_stack", mono_create_icall_signature ("void"), TRUE); - -#ifndef MONO_CROSS_COMPILE - if (mono_arm_have_tls_get ()) { - MonoTlsImplementation tls_imp = mono_arm_get_tls_implementation (); - - mono_register_jit_icall (tls_imp.get_tls_thunk, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE); - mono_register_jit_icall (tls_imp.set_tls_thunk, "mono_set_tls_key", mono_create_icall_signature ("void ptr ptr"), TRUE); - - get_tls_tramp = tls_imp.get_tls_thunk; - - if (tls_imp.get_tls_thunk_end) { - mono_tramp_info_register ( - mono_tramp_info_create ( - "mono_get_tls_key", - (guint8*)tls_imp.get_tls_thunk, - (guint8*)tls_imp.get_tls_thunk_end - (guint8*)tls_imp.get_tls_thunk, - NULL, - mono_arch_get_cie_program () - ), - NULL - ); - mono_tramp_info_register ( - mono_tramp_info_create ( - "mono_set_tls_key", - (guint8*)tls_imp.set_tls_thunk, - (guint8*)tls_imp.set_tls_thunk_end - (guint8*)tls_imp.set_tls_thunk, - NULL, - mono_arch_get_cie_program () - ), - NULL - ); - } - } -#endif } #define patch_lis_ori(ip,val) do {\ @@ -7539,7 +7405,7 @@ mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) gpointer mono_arch_get_get_tls_tramp (void) { - return get_tls_tramp; + return NULL; } static guint8*