#include "mini-gc.h"
#include "mono/arch/arm/arm-vfp-codegen.h"
-#if defined(HAVE_KW_THREAD) && defined(__linux__) \
+#if (defined(HAVE_KW_THREAD) && defined(__linux__) && defined(__ARM_EABI__)) \
|| defined(TARGET_ANDROID) \
|| (defined(TARGET_IOS) && !defined(TARGET_WATCHOS))
#define HAVE_FAST_TLS
static int i8_align;
-static volatile int ss_trigger_var = 0;
-
static gpointer single_step_tramp, breakpoint_tramp;
/*
#endif /* #ifndef DISABLE_JIT */
-#ifndef MONO_CROSS_COMPILE
-static gboolean
-mono_arm_have_fast_tls (void)
-{
- if (mini_get_debug_options ()->arm_use_fallback_tls)
- return FALSE;
-#if (defined(HAVE_KW_THREAD) && defined(__linux__)) \
- || defined(TARGET_ANDROID)
- guint32* kuser_get_tls = (void*)0xffff0fe0;
- guint32 expected [] = {0xee1d0f70, 0xe12fff1e};
-
- /* Expecting mrc + bx lr in the kuser_get_tls kernel helper */
- return memcmp (kuser_get_tls, expected, 8) == 0;
-#elif defined(TARGET_IOS)
- guint32 expected [] = {0x1f70ee1d, 0x0103f021, 0x0020f851, 0xbf004770};
- /* Discard thumb bit */
- guint32* pthread_getspecific_addr = (guint32*) ((guint32)pthread_getspecific & 0xfffffffe);
- return memcmp ((void*)pthread_getspecific_addr, expected, 16) == 0;
-#else
- return FALSE;
-#endif
-}
-#endif
-
/*
* mono_arm_have_tls_get:
*
mono_mutex_init_recursive (&mini_arch_mutex);
if (mini_get_debug_options ()->soft_breakpoints) {
- single_step_tramp = mini_get_single_step_trampoline ();
breakpoint_tramp = mini_get_breakpoint_trampoline ();
} else {
ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
ainfo->reg = fpr;
ainfo->nregs = nfields;
ainfo->esize = esize;
- fpr += nfields;
+ if (esize == 4)
+ fpr += nfields;
+ else
+ fpr += nfields * 2;
break;
} else {
fpr = ARM_VFP_F16;
offset += size;
}
- if (cfg->arch.seq_point_read_var) {
+ if (cfg->arch.seq_point_ss_method_var) {
MonoInst *ins;
- ins = cfg->arch.seq_point_read_var;
-
- size = 4;
- align = 4;
- offset += align - 1;
- offset &= ~(align - 1);
- ins->opcode = OP_REGOFFSET;
- ins->inst_basereg = cfg->frame_reg;
- ins->inst_offset = offset;
- offset += size;
-
ins = cfg->arch.seq_point_ss_method_var;
size = 4;
align = 4;
if (cfg->gen_sdb_seq_points) {
if (cfg->soft_breakpoints) {
- MonoInst *ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
- ins->flags |= MONO_INST_VOLATILE;
- cfg->arch.seq_point_read_var = ins;
+ MonoInst *ins;
ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
ins->flags |= MONO_INST_VOLATILE;
case RegTypeIRegPair:
case RegTypeBase:
case RegTypeBaseGen:
- linfo->args [i].storage = LLVMArgInIReg;
+ linfo->args [i].storage = LLVMArgNormal;
break;
case RegTypeStructByVal:
linfo->args [i].storage = LLVMArgAsIArgs;
call->float_args = g_slist_append_mempool (cfg->mempool, call->float_args, fad);
} else {
- add_outarg_reg (cfg, call, RegTypeFP, ainfo->reg + i, load);
+ add_outarg_reg (cfg, call, RegTypeFP, ainfo->reg + (i * 2), load);
}
}
break;
int i;
MonoInst *info_var = cfg->arch.seq_point_info_var;
MonoInst *ss_trigger_page_var = cfg->arch.ss_trigger_page_var;
- MonoInst *ss_read_var = cfg->arch.seq_point_read_var;
MonoInst *ss_method_var = cfg->arch.seq_point_ss_method_var;
MonoInst *bp_method_var = cfg->arch.seq_point_bp_method_var;
MonoInst *var;
g_assert (arm_is_imm12 (info_var->inst_offset));
}
- if (!cfg->soft_breakpoints) {
+ if (!cfg->soft_breakpoints && !cfg->compile_aot) {
/*
* Read from the single stepping trigger page. This will cause a
* SIGSEGV when single stepping is enabled.
if (ins->flags & MONO_INST_SINGLE_STEP_LOC) {
if (cfg->soft_breakpoints) {
- /* Load the address of the sequence point trigger variable. */
- var = ss_read_var;
+ /* Load the address of the sequence point method variable. */
+ var = ss_method_var;
g_assert (var);
g_assert (var->opcode == OP_REGOFFSET);
g_assert (arm_is_imm12 (var->inst_offset));
/* Read the value and check whether it is non-zero. */
ARM_LDR_IMM (code, dreg, dreg, 0);
ARM_CMP_REG_IMM (code, dreg, 0, 0);
-
- /* Load the address of the sequence point method. */
- var = ss_method_var;
- g_assert (var);
- g_assert (var->opcode == OP_REGOFFSET);
- g_assert (arm_is_imm12 (var->inst_offset));
- ARM_LDR_IMM (code, dreg, var->inst_basereg, var->inst_offset);
-
/* Call it conditionally. */
ARM_BLX_REG_COND (code, ARMCOND_NE, dreg);
} else {
#ifndef MONO_CROSS_COMPILE
if (mono_arm_have_tls_get ()) {
- if (mono_arm_have_fast_tls ()) {
- mono_register_jit_icall (mono_fast_get_tls_key, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE);
- mono_register_jit_icall (mono_fast_set_tls_key, "mono_set_tls_key", mono_create_icall_signature ("void ptr ptr"), TRUE);
+ 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);
+ if (tls_imp.get_tls_thunk_end) {
mono_tramp_info_register (
mono_tramp_info_create (
"mono_get_tls_key",
- (guint8*)mono_fast_get_tls_key,
- (guint8*)mono_fast_get_tls_key_end - (guint8*)mono_fast_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 ()
),
mono_tramp_info_register (
mono_tramp_info_create (
"mono_set_tls_key",
- (guint8*)mono_fast_set_tls_key,
- (guint8*)mono_fast_set_tls_key_end - (guint8*)mono_fast_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
);
- } else {
- g_warning ("No fast tls on device. Using fallbacks.");
- mono_register_jit_icall (mono_fallback_get_tls_key, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE);
- mono_register_jit_icall (mono_fallback_set_tls_key, "mono_set_tls_key", mono_create_icall_signature ("void ptr ptr"), TRUE);
}
}
#endif
}
}
- if (cfg->arch.seq_point_read_var) {
- MonoInst *read_ins = cfg->arch.seq_point_read_var;
+ if (cfg->arch.seq_point_ss_method_var) {
MonoInst *ss_method_ins = cfg->arch.seq_point_ss_method_var;
MonoInst *bp_method_ins = cfg->arch.seq_point_bp_method_var;
#ifdef USE_JUMP_TABLES
gpointer *jte;
#endif
- g_assert (read_ins->opcode == OP_REGOFFSET);
- g_assert (arm_is_imm12 (read_ins->inst_offset));
g_assert (ss_method_ins->opcode == OP_REGOFFSET);
g_assert (arm_is_imm12 (ss_method_ins->inst_offset));
g_assert (bp_method_ins->opcode == OP_REGOFFSET);
#ifdef USE_JUMP_TABLES
jte = mono_jumptable_add_entries (3);
- jte [0] = (gpointer)&ss_trigger_var;
- jte [1] = single_step_tramp;
- jte [2] = breakpoint_tramp;
+ jte [0] = &single_step_tramp;
+ jte [1] = breakpoint_tramp;
code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_LR);
#else
ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC);
ARM_B (code, 2);
- *(volatile int **)code = &ss_trigger_var;
- code += 4;
- *(gpointer*)code = single_step_tramp;
+ *(gpointer*)code = &single_step_tramp;
code += 4;
*(gpointer*)code = breakpoint_tramp;
code += 4;
#endif
ARM_LDR_IMM (code, ARMREG_IP, ARMREG_LR, 0);
- ARM_STR_IMM (code, ARMREG_IP, read_ins->inst_basereg, read_ins->inst_offset);
- ARM_LDR_IMM (code, ARMREG_IP, ARMREG_LR, 4);
ARM_STR_IMM (code, ARMREG_IP, ss_method_ins->inst_basereg, ss_method_ins->inst_offset);
- ARM_LDR_IMM (code, ARMREG_IP, ARMREG_LR, 8);
+ ARM_LDR_IMM (code, ARMREG_IP, ARMREG_LR, 4);
ARM_STR_IMM (code, ARMREG_IP, bp_method_ins->inst_basereg, bp_method_ins->inst_offset);
}
if (ss_trigger_page)
mono_mprotect (ss_trigger_page, mono_pagesize (), 0);
else
- ss_trigger_var = 1;
+ single_step_tramp = mini_get_single_step_trampoline ();
}
/*
if (ss_trigger_page)
mono_mprotect (ss_trigger_page, mono_pagesize (), MONO_MMAP_READ);
else
- ss_trigger_var = 0;
+ single_step_tramp = NULL;
}
#if __APPLE__