#define HAVE_AEABI_READ_TP 1
#endif
+#ifdef ARM_FPU_VFP_HARD
+#define ARM_FPU_VFP 1
+#endif
+
#ifdef ARM_FPU_FPA
#define IS_FPA 1
#else
* Returns the size of the activation frame.
*/
int
-mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
+mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info)
{
int k, frame_size = 0;
guint32 size, align, pad;
ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, sizeof (MonoContext));
/* save ip, lr and pc into their correspodings ctx.regs slots. */
- ARM_STR_IMM (code, ARMREG_IP, ARMREG_SP, G_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_IP);
+ ARM_STR_IMM (code, ARMREG_IP, ARMREG_SP, G_STRUCT_OFFSET (MonoContext, regs) + sizeof (mgreg_t) * ARMREG_IP);
ARM_STR_IMM (code, ARMREG_LR, ARMREG_SP, G_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_LR);
ARM_STR_IMM (code, ARMREG_LR, ARMREG_SP, G_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_PC);
/* make ctx.esp hold the actual value of sp at the beginning of this method. */
ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_FP, sizeof (MonoContext));
ARM_STR_IMM (code, ARMREG_R0, ARMREG_IP, 4 * ARMREG_SP);
- ARM_STR_IMM (code, ARMREG_R0, ARMREG_FP, G_STRUCT_OFFSET (MonoContext, esp));
+ ARM_STR_IMM (code, ARMREG_R0, ARMREG_FP, G_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_SP);
/* make ctx.eip hold the address of the call. */
ARM_SUB_REG_IMM8 (code, ARMREG_LR, ARMREG_LR, 4);
- ARM_STR_IMM (code, ARMREG_LR, ARMREG_SP, G_STRUCT_OFFSET (MonoContext, eip));
+ ARM_STR_IMM (code, ARMREG_LR, ARMREG_SP, G_STRUCT_OFFSET (MonoContext, pc));
/* r0 now points to the MonoContext */
ARM_MOV_REG_REG (code, ARMREG_R0, ARMREG_FP);
ARM_BLX_REG (code, ARMREG_IP);
/* we're back; save ctx.eip and ctx.esp into the corresponding regs slots. */
- ARM_LDR_IMM (code, ARMREG_R0, ARMREG_FP, G_STRUCT_OFFSET (MonoContext, eip));
+ ARM_LDR_IMM (code, ARMREG_R0, ARMREG_FP, G_STRUCT_OFFSET (MonoContext, pc));
ARM_STR_IMM (code, ARMREG_R0, ARMREG_FP, G_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_LR);
ARM_STR_IMM (code, ARMREG_R0, ARMREG_FP, G_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_PC);
- ARM_LDR_IMM (code, ARMREG_R0, ARMREG_FP, G_STRUCT_OFFSET (MonoContext, esp));
- ARM_STR_IMM (code, ARMREG_R0, ARMREG_FP, G_STRUCT_OFFSET (MonoContext, regs) + 4 * ARMREG_SP);
/* make ip point to the regs array, then restore everything, including pc. */
ARM_ADD_REG_IMM8 (code, ARMREG_IP, ARMREG_FP, G_STRUCT_OFFSET (MonoContext, regs));
#ifdef ARM_FPU_FPA
arm_fpu = MONO_ARM_FPU_FPA;
+#elif defined(ARM_FPU_VFP_HARD)
+ arm_fpu = MONO_ARM_FPU_VFP_HARD;
#elif defined(ARM_FPU_VFP)
arm_fpu = MONO_ARM_FPU_VFP;
#else
* This function returns the optimizations supported on this cpu.
*/
guint32
-mono_arch_cpu_optimizazions (guint32 *exclude_mask)
+mono_arch_cpu_optimizations (guint32 *exclude_mask)
{
guint32 opts = 0;
const char *cpu_arch = getenv ("MONO_CPU_ARCH");
return opts;
}
+/*
+ * This function test for all SIMD functions supported.
+ *
+ * Returns a bitmask corresponding to all supported versions.
+ *
+ */
+guint32
+mono_arch_cpu_enumerate_simd_versions (void)
+{
+ /* SIMD is currently unimplemented */
+ return 0;
+}
+
+
#ifndef DISABLE_JIT
static gboolean
#ifndef DISABLE_JIT
-G_GNUC_UNUSED static void
-break_count (void)
-{
-}
-
-G_GNUC_UNUSED static gboolean
-debug_count (void)
-{
- static int count = 0;
- count ++;
-
- if (!getenv ("COUNT"))
- return TRUE;
-
- if (count == atoi (getenv ("COUNT"))) {
- break_count ();
- }
-
- if (count > atoi (getenv ("COUNT"))) {
- return FALSE;
- }
-
- return TRUE;
-}
-
static gboolean
debug_omit_fp (void)
{
#if 0
- return debug_count ();
+ return mono_debug_count ();
#else
return TRUE;
#endif
emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo)
{
MonoMethodSignature *tmp_sig;
- MonoInst *sig_arg;
+ int sig_reg;
if (call->tail_call)
NOT_IMPLEMENTED;
- /* FIXME: Add support for signature tokens to AOT */
- cfg->disable_aot = TRUE;
-
g_assert (cinfo->sig_cookie.storage == RegTypeBase);
/*
tmp_sig->sentinelpos = 0;
memcpy (tmp_sig->params, call->signature->params + call->signature->sentinelpos, tmp_sig->param_count * sizeof (MonoType*));
- MONO_INST_NEW (cfg, sig_arg, OP_ICONST);
- sig_arg->dreg = mono_alloc_ireg (cfg);
- sig_arg->inst_p0 = tmp_sig;
- MONO_ADD_INS (cfg->cbb, sig_arg);
+ sig_reg = mono_alloc_ireg (cfg);
+ MONO_EMIT_NEW_SIGNATURECONST (cfg, sig_reg, tmp_sig);
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, ARMREG_SP, cinfo->sig_cookie.offset, sig_arg->dreg);
+ MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, ARMREG_SP, cinfo->sig_cookie.offset, sig_reg);
}
#ifdef ENABLE_LLVM
ARMCOND_LO
};
-#define NEW_INS(cfg,dest,op) do { \
+#define ADD_NEW_INS(cfg,dest,op) do { \
MONO_INST_NEW ((cfg), (dest), (op)); \
mono_bblock_insert_before_ins (bb, ins, (dest)); \
} while (0)
case OP_IOR_IMM:
case OP_IXOR_IMM:
if ((imm8 = mono_arm_is_rotated_imm8 (ins->inst_imm, &rot_amount)) < 0) {
- NEW_INS (cfg, temp, OP_ICONST);
+ ADD_NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_alloc_ireg (cfg);
ins->sreg2 = temp->dreg;
ins->inst_imm = imm8;
break;
}
- NEW_INS (cfg, temp, OP_ICONST);
+ ADD_NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_alloc_ireg (cfg);
ins->sreg2 = temp->dreg;
ins->next->opcode = OP_COND_EXC_NC;
break;
case OP_LOCALLOC_IMM:
- NEW_INS (cfg, temp, OP_ICONST);
+ ADD_NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_alloc_ireg (cfg);
ins->sreg1 = temp->dreg;
*/
if (arm_is_imm12 (ins->inst_offset))
break;
- NEW_INS (cfg, temp, OP_ICONST);
+ ADD_NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_offset;
temp->dreg = mono_alloc_ireg (cfg);
ins->sreg2 = temp->dreg;
case OP_LOADI1_MEMBASE:
if (arm_is_imm8 (ins->inst_offset))
break;
- NEW_INS (cfg, temp, OP_ICONST);
+ ADD_NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_offset;
temp->dreg = mono_alloc_ireg (cfg);
ins->sreg2 = temp->dreg;
break;
low_imm = ins->inst_offset & 0x1ff;
if ((imm8 = mono_arm_is_rotated_imm8 (ins->inst_offset & ~0x1ff, &rot_amount)) >= 0) {
- NEW_INS (cfg, temp, OP_ADD_IMM);
+ ADD_NEW_INS (cfg, temp, OP_ADD_IMM);
temp->inst_imm = ins->inst_offset & ~0x1ff;
temp->sreg1 = ins->inst_basereg;
temp->dreg = mono_alloc_ireg (cfg);
ins->inst_basereg = temp->dreg;
ins->inst_offset = low_imm;
- break;
+ } else {
+ MonoInst *add_ins;
+
+ ADD_NEW_INS (cfg, temp, OP_ICONST);
+ temp->inst_c0 = ins->inst_offset;
+ temp->dreg = mono_alloc_ireg (cfg);
+
+ ADD_NEW_INS (cfg, add_ins, OP_IADD);
+ add_ins->sreg1 = ins->inst_basereg;
+ add_ins->sreg2 = temp->dreg;
+ add_ins->dreg = mono_alloc_ireg (cfg);
+
+ ins->inst_basereg = add_ins->dreg;
+ ins->inst_offset = 0;
}
- /* VFP/FPA doesn't have indexed load instructions */
- g_assert_not_reached ();
break;
case OP_STORE_MEMBASE_REG:
case OP_STOREI4_MEMBASE_REG:
case OP_STOREI1_MEMBASE_REG:
if (arm_is_imm12 (ins->inst_offset))
break;
- NEW_INS (cfg, temp, OP_ICONST);
+ ADD_NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_offset;
temp->dreg = mono_alloc_ireg (cfg);
ins->sreg2 = temp->dreg;
case OP_STOREI2_MEMBASE_REG:
if (arm_is_imm8 (ins->inst_offset))
break;
- NEW_INS (cfg, temp, OP_ICONST);
+ ADD_NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_offset;
temp->dreg = mono_alloc_ireg (cfg);
ins->sreg2 = temp->dreg;
break;
low_imm = ins->inst_offset & 0x1ff;
if ((imm8 = mono_arm_is_rotated_imm8 (ins->inst_offset & ~ 0x1ff, &rot_amount)) >= 0 && arm_is_fpimm8 (low_imm)) {
- NEW_INS (cfg, temp, OP_ADD_IMM);
+ ADD_NEW_INS (cfg, temp, OP_ADD_IMM);
temp->inst_imm = ins->inst_offset & ~0x1ff;
temp->sreg1 = ins->inst_destbasereg;
temp->dreg = mono_alloc_ireg (cfg);
ins->inst_destbasereg = temp->dreg;
ins->inst_offset = low_imm;
- break;
+ } else {
+ MonoInst *add_ins;
+
+ ADD_NEW_INS (cfg, temp, OP_ICONST);
+ temp->inst_c0 = ins->inst_offset;
+ temp->dreg = mono_alloc_ireg (cfg);
+
+ ADD_NEW_INS (cfg, add_ins, OP_IADD);
+ add_ins->sreg1 = ins->inst_destbasereg;
+ add_ins->sreg2 = temp->dreg;
+ add_ins->dreg = mono_alloc_ireg (cfg);
+
+ ins->inst_destbasereg = add_ins->dreg;
+ ins->inst_offset = 0;
}
- /*g_print ("fail with: %d (%d, %d)\n", ins->inst_offset, ins->inst_offset & ~0x1ff, low_imm);*/
- /* VFP/FPA doesn't have indexed store instructions */
- g_assert_not_reached ();
break;
case OP_STORE_MEMBASE_IMM:
case OP_STOREI1_MEMBASE_IMM:
case OP_STOREI2_MEMBASE_IMM:
case OP_STOREI4_MEMBASE_IMM:
- NEW_INS (cfg, temp, OP_ICONST);
+ ADD_NEW_INS (cfg, temp, OP_ICONST);
temp->inst_c0 = ins->inst_imm;
temp->dreg = mono_alloc_ireg (cfg);
ins->sreg1 = temp->dreg;
/* Add the offset */
val = ((offset / 4) * sizeof (guint8*)) + G_STRUCT_OFFSET (SeqPointInfo, bp_addrs);
ARM_ADD_REG_IMM (code, dreg, dreg, (val & 0xFF), 0);
- /*
- * Have to emit nops to keep the difference between the offset
- * stored in seq_points and breakpoint instruction constant,
- * mono_arch_get_ip_for_breakpoint () depends on this.
- */
if (val & 0xFF00)
ARM_ADD_REG_IMM (code, dreg, dreg, (val & 0xFF00) >> 8, 24);
- else
- ARM_NOP (code);
if (val & 0xFF0000)
ARM_ADD_REG_IMM (code, dreg, dreg, (val & 0xFF0000) >> 16, 16);
- else
- ARM_NOP (code);
g_assert (!(val & 0xFF000000));
/* Load the info->bp_addrs [offset], which is either 0 or the address of a trigger page */
ARM_LDR_IMM (code, dreg, dreg, 0);
}
case OP_START_HANDLER: {
MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region);
+ int i, rot_amount;
+
+ /* Reserve a param area, see filter-stack.exe */
+ if (cfg->param_area) {
+ if ((i = mono_arm_is_rotated_imm8 (cfg->param_area, &rot_amount)) >= 0) {
+ ARM_SUB_REG_IMM (code, ARMREG_SP, ARMREG_SP, i, rot_amount);
+ } else {
+ code = mono_arm_emit_load_imm (code, ARMREG_IP, cfg->param_area);
+ ARM_SUB_REG_REG (code, ARMREG_SP, ARMREG_SP, ARMREG_IP);
+ }
+ }
if (arm_is_imm12 (spvar->inst_offset)) {
ARM_STR_IMM (code, ARMREG_LR, spvar->inst_basereg, spvar->inst_offset);
}
case OP_ENDFILTER: {
MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region);
+ int i, rot_amount;
+
+ /* Free the param area */
+ if (cfg->param_area) {
+ if ((i = mono_arm_is_rotated_imm8 (cfg->param_area, &rot_amount)) >= 0) {
+ ARM_ADD_REG_IMM (code, ARMREG_SP, ARMREG_SP, i, rot_amount);
+ } else {
+ code = mono_arm_emit_load_imm (code, ARMREG_IP, cfg->param_area);
+ ARM_ADD_REG_REG (code, ARMREG_SP, ARMREG_SP, ARMREG_IP);
+ }
+ }
if (ins->sreg1 != ARMREG_R0)
ARM_MOV_REG_REG (code, ARMREG_R0, ins->sreg1);
}
case OP_ENDFINALLY: {
MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region);
+ int i, rot_amount;
+
+ /* Free the param area */
+ if (cfg->param_area) {
+ if ((i = mono_arm_is_rotated_imm8 (cfg->param_area, &rot_amount)) >= 0) {
+ ARM_ADD_REG_IMM (code, ARMREG_SP, ARMREG_SP, i, rot_amount);
+ } else {
+ code = mono_arm_emit_load_imm (code, ARMREG_IP, cfg->param_area);
+ ARM_ADD_REG_REG (code, ARMREG_SP, ARMREG_SP, ARMREG_IP);
+ }
+ }
if (arm_is_imm12 (spvar->inst_offset)) {
ARM_LDR_IMM (code, ARMREG_IP, spvar->inst_basereg, spvar->inst_offset);
}
break;
case 8:
- g_assert (arm_is_imm12 (inst->inst_offset));
- ARM_STR_IMM (code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
- g_assert (arm_is_imm12 (inst->inst_offset + 4));
- ARM_STR_IMM (code, ainfo->reg + 1, inst->inst_basereg, inst->inst_offset + 4);
+ if (arm_is_imm12 (inst->inst_offset)) {
+ ARM_STR_IMM (code, ainfo->reg, inst->inst_basereg, inst->inst_offset);
+ } else {
+ code = mono_arm_emit_load_imm (code, ARMREG_IP, inst->inst_offset);
+ ARM_STR_REG_REG (code, ainfo->reg, inst->inst_basereg, ARMREG_IP);
+ }
+ if (arm_is_imm12 (inst->inst_offset + 4)) {
+ ARM_STR_IMM (code, ainfo->reg + 1, inst->inst_basereg, inst->inst_offset + 4);
+ } else {
+ code = mono_arm_emit_load_imm (code, ARMREG_IP, inst->inst_offset + 4);
+ ARM_STR_REG_REG (code, ainfo->reg + 1, inst->inst_basereg, ARMREG_IP);
+ }
break;
default:
if (arm_is_imm12 (inst->inst_offset)) {
pos++;
}
- if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
- if (cfg->compile_aot)
- /* AOT code is only used in the root domain */
- code = mono_arm_emit_load_imm (code, ARMREG_R0, 0);
- else
- code = mono_arm_emit_load_imm (code, ARMREG_R0, (guint32)cfg->domain);
- mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
- (gpointer)"mono_jit_thread_attach");
- code = emit_call_seq (cfg, code);
- }
-
if (method->save_lmf)
code = emit_save_lmf (cfg, code, alloc_size - lmf_offset);
#endif /* #ifndef DISABLE_JIT */
-static gboolean tls_offset_inited = FALSE;
-
void
-mono_arch_setup_jit_tls_data (MonoJitTlsData *tls)
+mono_arch_finish_init (void)
{
- if (!tls_offset_inited) {
- tls_offset_inited = TRUE;
-
- lmf_tls_offset = mono_get_lmf_tls_offset ();
- lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset ();
- }
+ lmf_tls_offset = mono_get_lmf_tls_offset ();
+ lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset ();
}
void
mgreg_t
mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
{
- if (reg == ARMREG_SP)
- return ctx->esp;
- else
- return ctx->regs [reg];
+ return ctx->regs [reg];
}
void
mono_arch_context_set_int_reg (MonoContext *ctx, int reg, mgreg_t val)
{
- if (reg == ARMREG_SP)
- ctx->esp = val;
- else
- ctx->regs [reg] = val;
+ ctx->regs [reg] = val;
}
/*
}
}
-guint8*
-mono_arch_get_ip_for_breakpoint (MonoJitInfo *ji, MonoContext *ctx)
-{
- guint8 *ip = MONO_CONTEXT_GET_IP (ctx);
-
- if (ji->from_aot)
- ip -= 6 * 4;
- else if (mini_get_debug_options ()->soft_breakpoints)
- ip -= 4;
- else
- ip -= 12;
-
- return ip;
-}
-
-guint8*
-mono_arch_get_ip_for_single_step (MonoJitInfo *ji, MonoContext *ctx)
-{
- guint8 *ip = MONO_CONTEXT_GET_IP (ctx);
-
- ip += 4;
-
- return ip;
-}
-
/*
* mono_arch_skip_breakpoint:
*
* See mini-amd64.c for docs.
*/
void
-mono_arch_skip_breakpoint (MonoContext *ctx)
+mono_arch_skip_breakpoint (MonoContext *ctx, MonoJitInfo *ji)
{
MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + 4);
}