X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-x86.c;h=35f56d0f984fd50aba7cf01c9471fb046e95bf2a;hb=69ba0b04fd7f45f303da4cd537b1a2b158b5fd75;hp=f82376ab519fcd81899af3088714b204898b33b5;hpb=630116d1b60070c2a0b09f5912df3bdd5c83bacf;p=mono.git diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index f82376ab519..35f56d0f984 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -45,9 +45,9 @@ static gboolean optimize_for_xen = TRUE; #endif /* This mutex protects architecture specific caches */ -#define mono_mini_arch_lock() EnterCriticalSection (&mini_arch_mutex) -#define mono_mini_arch_unlock() LeaveCriticalSection (&mini_arch_mutex) -static CRITICAL_SECTION mini_arch_mutex; +#define mono_mini_arch_lock() mono_mutex_lock (&mini_arch_mutex) +#define mono_mini_arch_unlock() mono_mutex_unlock (&mini_arch_mutex) +static mono_mutex_t mini_arch_mutex; #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) @@ -758,7 +758,7 @@ mono_arch_cpu_init (void) void mono_arch_init (void) { - InitializeCriticalSection (&mini_arch_mutex); + mono_mutex_init_recursive (&mini_arch_mutex); ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ); bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT); @@ -781,7 +781,7 @@ mono_arch_cleanup (void) mono_vfree (ss_trigger_page, mono_pagesize ()); if (bp_trigger_page) mono_vfree (bp_trigger_page, mono_pagesize ()); - DeleteCriticalSection (&mini_arch_mutex); + mono_mutex_destroy (&mini_arch_mutex); } /* @@ -868,7 +868,7 @@ mono_arch_is_int_overflow (void *sigctx, void *info) MonoContext ctx; guint8* ip; - mono_arch_sigctx_to_monoctx (sigctx, &ctx); + mono_sigctx_to_monoctx (sigctx, &ctx); ip = (guint8*)ctx.eip; @@ -1217,10 +1217,6 @@ mono_arch_create_vars (MonoCompile *cfg) cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG); } -#ifdef MONO_X86_NO_PUSHES - cfg->arch.no_pushes = TRUE; -#endif - if (cfg->method->save_lmf) { cfg->create_lmf_var = TRUE; cfg->lmf_ir = TRUE; @@ -1279,17 +1275,9 @@ emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo) if (cfg->compile_aot) { sig_reg = mono_alloc_ireg (cfg); MONO_EMIT_NEW_SIGNATURECONST (cfg, sig_reg, tmp_sig); - if (cfg->arch.no_pushes) { - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, cinfo->sig_cookie.offset, sig_reg); - } else { - MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, sig_reg); - } + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, cinfo->sig_cookie.offset, sig_reg); } else { - if (cfg->arch.no_pushes) { - MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, X86_ESP, cinfo->sig_cookie.offset, tmp_sig); - } else { - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_X86_PUSH_IMM, -1, -1, tmp_sig); - } + MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, X86_ESP, cinfo->sig_cookie.offset, tmp_sig); } } @@ -1415,7 +1403,7 @@ emit_gc_param_slot_def (MonoCompile *cfg, int sp_offset, MonoType *t) MonoInst *def; /* Needs checking if the feature will be enabled again */ - g_assert (!cfg->arch.no_pushes); + g_assert_not_reached (); /* On x86, the offsets are from the sp value before the start of the call sequence */ if (t == NULL) @@ -1444,19 +1432,6 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG)) sentinelpos = sig->sentinelpos + (sig->hasthis ? 1 : 0); - if (cinfo->need_stack_align && !cfg->arch.no_pushes) { - MONO_INST_NEW (cfg, arg, OP_SUB_IMM); - arg->dreg = X86_ESP; - arg->sreg1 = X86_ESP; - arg->inst_imm = cinfo->stack_align_amount; - MONO_ADD_INS (cfg->cbb, arg); - for (i = 0; i < cinfo->stack_align_amount; i += sizeof (mgreg_t)) { - sp_offset += 4; - - emit_gc_param_slot_def (cfg, sp_offset, NULL); - } - } - if (sig_ret && MONO_TYPE_ISSTRUCT (sig_ret)) { if (cinfo->ret.storage == ArgValuetypeInReg) { /* @@ -1465,6 +1440,10 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) * result there. */ call->vret_in_reg = TRUE; +#if defined(__APPLE__) + if (cinfo->ret.pair_storage [0] == ArgOnDoubleFpStack || cinfo->ret.pair_storage [0] == ArgOnFloatFpStack) + call->vret_in_reg_fp = TRUE; +#endif if (call->vret_var) NULLIFY_INS (call->vret_var); } @@ -1475,7 +1454,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) /* Handle the case where there are no implicit arguments */ if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (n == sentinelpos)) { emit_sig_cookie (cfg, call, cinfo); - sp_offset = (cfg->arch.no_pushes) ? cinfo->sig_cookie.offset : (sp_offset + 4); + sp_offset = cinfo->sig_cookie.offset; emit_gc_param_slot_def (cfg, sp_offset, NULL); } @@ -1487,23 +1466,15 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) if (cinfo->vtype_retaddr && cinfo->vret_arg_index == 1 && i == 0) { MonoInst *vtarg; + /* Push the vret arg before the first argument */ - if (cfg->arch.no_pushes) { - MONO_INST_NEW (cfg, vtarg, OP_STORE_MEMBASE_REG); - vtarg->type = STACK_MP; - vtarg->inst_destbasereg = X86_ESP; - vtarg->sreg1 = call->vret_var->dreg; - vtarg->inst_offset = cinfo->ret.offset; - MONO_ADD_INS (cfg->cbb, vtarg); - sp_offset = cinfo->ret.offset; - } else { - MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH); - vtarg->type = STACK_MP; - vtarg->sreg1 = call->vret_var->dreg; - MONO_ADD_INS (cfg->cbb, vtarg); - sp_offset += 4; - } - emit_gc_param_slot_def (cfg, sp_offset, NULL); + MONO_INST_NEW (cfg, vtarg, OP_STORE_MEMBASE_REG); + vtarg->type = STACK_MP; + vtarg->inst_destbasereg = X86_ESP; + vtarg->sreg1 = call->vret_var->dreg; + vtarg->inst_offset = cinfo->ret.offset; + MONO_ADD_INS (cfg->cbb, vtarg); + emit_gc_param_slot_def (cfg, cinfo->ret.offset, NULL); } if (i >= sig->hasthis) @@ -1555,8 +1526,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) MONO_ADD_INS (cfg->cbb, arg); if (ainfo->storage != ArgValuetypeInReg) { - sp_offset = (cfg->arch.no_pushes) ? ainfo->offset : (sp_offset + size); - emit_gc_param_slot_def (cfg, sp_offset, orig_type); + emit_gc_param_slot_def (cfg, ainfo->offset, orig_type); } } } else { @@ -1564,47 +1534,21 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) case ArgOnStack: if (!t->byref) { if (t->type == MONO_TYPE_R4) { - if (cfg->arch.no_pushes) { - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); - } else { - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 4); - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG, X86_ESP, 0, in->dreg); - } + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); argsize = 4; } else if (t->type == MONO_TYPE_R8) { - if (cfg->arch.no_pushes) { - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); - } else { - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 8); - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, X86_ESP, 0, in->dreg); - } + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); argsize = 8; } else if (t->type == MONO_TYPE_I8 || t->type == MONO_TYPE_U8) { - if (cfg->arch.no_pushes) { - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset + 4, in->dreg + 2); - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg + 1); - } else { - MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, in->dreg + 2); - MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, in->dreg + 1); - sp_offset += 4; - } + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset + 4, in->dreg + 2); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg + 1); argsize = 4; } else { - if (cfg->arch.no_pushes) { - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); - } else { - arg->opcode = OP_X86_PUSH; - MONO_ADD_INS (cfg->cbb, arg); - } + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); argsize = 4; } } else { - if (cfg->arch.no_pushes) { - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); - } else { - arg->opcode = OP_X86_PUSH; - MONO_ADD_INS (cfg->cbb, arg); - } + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); argsize = 4; } break; @@ -1618,8 +1562,6 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) g_assert_not_reached (); } - sp_offset = (cfg->arch.no_pushes) ? ainfo->offset : (sp_offset + argsize); - if (cfg->compute_gc_maps) { if (argsize == 4) { /* FIXME: The == STACK_OBJ check might be fragile ? */ @@ -1627,20 +1569,16 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) /* this */ if (call->need_unbox_trampoline) /* The unbox trampoline transforms this into a managed pointer */ - emit_gc_param_slot_def (cfg, sp_offset, &mono_defaults.int_class->this_arg); + emit_gc_param_slot_def (cfg, ainfo->offset, &mono_defaults.int_class->this_arg); else - emit_gc_param_slot_def (cfg, sp_offset, &mono_defaults.object_class->byval_arg); + emit_gc_param_slot_def (cfg, ainfo->offset, &mono_defaults.object_class->byval_arg); } else { - emit_gc_param_slot_def (cfg, sp_offset, orig_type); + emit_gc_param_slot_def (cfg, ainfo->offset, orig_type); } } else { /* i8/r8 */ - for (j = 0; j < argsize; j += 4) { - if (cfg->arch.no_pushes) - emit_gc_param_slot_def (cfg, sp_offset + j, NULL); - else - emit_gc_param_slot_def (cfg, sp_offset - j, NULL); - } + for (j = 0; j < argsize; j += 4) + emit_gc_param_slot_def (cfg, ainfo->offset + j, NULL); } } } @@ -1648,8 +1586,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (i == sentinelpos)) { /* Emit the signature cookie just before the implicit arguments */ emit_sig_cookie (cfg, call, cinfo); - sp_offset = (cfg->arch.no_pushes) ? cinfo->sig_cookie.offset : (sp_offset + 4); - emit_gc_param_slot_def (cfg, sp_offset, NULL); + emit_gc_param_slot_def (cfg, cinfo->sig_cookie.offset, NULL); } } @@ -1669,29 +1606,13 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) mono_call_inst_add_outarg_reg (cfg, call, vtarg->dreg, cinfo->ret.reg, FALSE); } else if (cinfo->vtype_retaddr && cinfo->vret_arg_index == 0) { - if (cfg->arch.no_pushes) { - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, cinfo->ret.offset, call->vret_var->dreg); - sp_offset = cinfo->ret.offset; - } else { - MonoInst *vtarg; - MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH); - vtarg->type = STACK_MP; - vtarg->sreg1 = call->vret_var->dreg; - MONO_ADD_INS (cfg->cbb, vtarg); - sp_offset += 4; - } - emit_gc_param_slot_def (cfg, sp_offset, NULL); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, cinfo->ret.offset, call->vret_var->dreg); + emit_gc_param_slot_def (cfg, cinfo->ret.offset, NULL); } - - /* if the function returns a struct on stack, the called method already does a ret $0x4 */ - if (!cfg->arch.no_pushes) - cinfo->stack_usage -= cinfo->callee_stack_pop; } call->stack_usage = cinfo->stack_usage; call->stack_align_amount = cinfo->stack_align_amount; - if (!cfg->arch.no_pushes) - cfg->arch.param_area_size = MAX (cfg->arch.param_area_size, sp_offset); } void @@ -1699,7 +1620,6 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src) { MonoCallInst *call = (MonoCallInst*)ins->inst_p0; ArgInfo *ainfo = ins->inst_p1; - MonoInst *arg; int size = ins->backend.size; if (ainfo->storage == ArgValuetypeInReg) { @@ -1723,42 +1643,16 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src) else { if (cfg->gsharedvt && mini_is_gsharedvt_klass (cfg, ins->klass)) { /* Pass by addr */ - if (cfg->arch.no_pushes) { - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, src->dreg); - } else { - MONO_INST_NEW (cfg, arg, OP_X86_PUSH); - arg->sreg1 = src->dreg; - MONO_ADD_INS (cfg->cbb, arg); - } + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, src->dreg); } else if (size <= 4) { - if (cfg->arch.no_pushes) { - int dreg = mono_alloc_ireg (cfg); - MONO_EMIT_NEW_LOAD_MEMBASE (cfg, dreg, src->dreg, 0); - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, dreg); - } else { - MONO_INST_NEW (cfg, arg, OP_X86_PUSH_MEMBASE); - arg->sreg1 = src->dreg; - MONO_ADD_INS (cfg->cbb, arg); - } + int dreg = mono_alloc_ireg (cfg); + MONO_EMIT_NEW_LOAD_MEMBASE (cfg, dreg, src->dreg, 0); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, dreg); } else if (size <= 20) { - if (cfg->arch.no_pushes) { - mini_emit_memcpy (cfg, X86_ESP, ainfo->offset, src->dreg, 0, size, 4); - } else { - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, ALIGN_TO (size, 4)); - mini_emit_memcpy (cfg, X86_ESP, 0, src->dreg, 0, size, 4); - } + mini_emit_memcpy (cfg, X86_ESP, ainfo->offset, src->dreg, 0, size, 4); } else { - if (cfg->arch.no_pushes) { - // FIXME: Code growth - mini_emit_memcpy (cfg, X86_ESP, ainfo->offset, src->dreg, 0, size, 4); - } else { - MONO_INST_NEW (cfg, arg, OP_X86_PUSH_OBJ); - arg->inst_basereg = src->dreg; - arg->inst_offset = 0; - arg->inst_imm = size; - - MONO_ADD_INS (cfg->cbb, arg); - } + // FIXME: Code growth + mini_emit_memcpy (cfg, X86_ESP, ainfo->offset, src->dreg, 0, size, 4); } } } @@ -2301,7 +2195,7 @@ mono_emit_stack_alloc (MonoCompile *cfg, guchar *code, MonoInst* tree) x86_push_reg (code, X86_EDI); x86_mov_reg_imm (code, X86_ECX, (0x1000 >> 2)); x86_alu_reg_reg (code, X86_XOR, X86_EAX, X86_EAX); - if (cfg->param_area && cfg->arch.no_pushes) + if (cfg->param_area) x86_lea_membase (code, X86_EDI, X86_ESP, 12 + ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); else x86_lea_membase (code, X86_EDI, X86_ESP, 12); @@ -2351,7 +2245,7 @@ mono_emit_stack_alloc (MonoCompile *cfg, guchar *code, MonoInst* tree) x86_mov_reg_reg (code, X86_ECX, sreg, 4); x86_alu_reg_reg (code, X86_XOR, X86_EAX, X86_EAX); - if (cfg->param_area && cfg->arch.no_pushes) + if (cfg->param_area) x86_lea_membase (code, X86_EDI, X86_ESP, offset + ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); else x86_lea_membase (code, X86_EDI, X86_ESP, offset); @@ -2461,12 +2355,22 @@ mono_x86_emit_tls_get (guint8* code, int dreg, int tls_offset) * See the Under the Hood article in the May 1996 issue of Microsoft Systems * Journal and/or a disassembly of the TlsGet () function. */ - g_assert (tls_offset < 64); x86_prefix (code, X86_FS_PREFIX); x86_mov_reg_mem (code, dreg, 0x18, 4); - /* Dunno what this does but TlsGetValue () contains it */ - x86_alu_membase_imm (code, X86_AND, dreg, 0x34, 0); - x86_mov_reg_membase (code, dreg, dreg, 3600 + (tls_offset * 4), 4); + if (tls_offset < 64) { + x86_mov_reg_membase (code, dreg, dreg, 3600 + (tls_offset * 4), 4); + } else { + guint8 *buf [16]; + + g_assert (tls_offset < 0x440); + /* Load TEB->TlsExpansionSlots */ + x86_mov_reg_membase (code, dreg, dreg, 0xf94, 4); + x86_test_reg_reg (code, dreg, dreg); + buf [0] = code; + x86_branch (code, X86_CC_EQ, code, TRUE); + x86_mov_reg_membase (code, dreg, dreg, (tls_offset * 4) - 0x100, 4); + x86_patch (buf [0], code); + } #else if (optimize_for_xen) { x86_prefix (code, X86_GS_PREFIX); @@ -3386,65 +3290,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } ins->flags |= MONO_INST_GC_CALLSITE; ins->backend.pc_offset = code - cfg->native_code; - if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature) && !cfg->arch.no_pushes) { - /* a pop is one byte, while an add reg, imm is 3. So if there are 4 or 8 - * bytes to pop, we want to use pops. GCC does this (note it won't happen - * for P4 or i686 because gcc will avoid using pop push at all. But we aren't - * smart enough to do that optimization yet - * - * It turns out that on my P4, doing two pops for 8 bytes on the stack makes - * mcs botstrap slow down. However, doing 1 pop for 4 bytes creates a small, - * (most likely from locality benefits). People with other processors should - * check on theirs to see what happens. - */ - if (call->stack_usage == 4) { - /* we want to use registers that won't get used soon, so use - * ecx, as eax will get allocated first. edx is used by long calls, - * so we can't use that. - */ - - x86_pop_reg (code, X86_ECX); - } else { - x86_alu_reg_imm (code, X86_ADD, X86_ESP, call->stack_usage); - } - } else if (cinfo->callee_stack_pop && cfg->arch.no_pushes) { + if (cinfo->callee_stack_pop) { /* Have to compensate for the stack space popped by the callee */ x86_alu_reg_imm (code, X86_SUB, X86_ESP, cinfo->callee_stack_pop); } code = emit_move_return_value (cfg, ins, code); break; } - case OP_X86_PUSH: - g_assert (!cfg->arch.no_pushes); - x86_push_reg (code, ins->sreg1); - break; - case OP_X86_PUSH_IMM: - g_assert (!cfg->arch.no_pushes); - x86_push_imm (code, ins->inst_imm); - break; - case OP_X86_PUSH_MEMBASE: - g_assert (!cfg->arch.no_pushes); - x86_push_membase (code, ins->inst_basereg, ins->inst_offset); - break; - case OP_X86_PUSH_OBJ: - g_assert (!cfg->arch.no_pushes); - x86_alu_reg_imm (code, X86_SUB, X86_ESP, ins->inst_imm); - x86_push_reg (code, X86_EDI); - x86_push_reg (code, X86_ESI); - x86_push_reg (code, X86_ECX); - if (ins->inst_offset) - x86_lea_membase (code, X86_ESI, ins->inst_basereg, ins->inst_offset); - else - x86_mov_reg_reg (code, X86_ESI, ins->inst_basereg, 4); - x86_lea_membase (code, X86_EDI, X86_ESP, 12); - x86_mov_reg_imm (code, X86_ECX, (ins->inst_imm >> 2)); - x86_cld (code); - x86_prefix (code, X86_REP_PREFIX); - x86_movsd (code); - x86_pop_reg (code, X86_ECX); - x86_pop_reg (code, X86_ESI); - x86_pop_reg (code, X86_EDI); - break; case OP_X86_LEA: x86_lea_memindex (code, ins->dreg, ins->sreg1, ins->inst_imm, ins->sreg2, ins->backend.shift_amount); break; @@ -3460,8 +3312,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) x86_alu_reg_imm (code, X86_AND, ins->sreg1, ~(MONO_ARCH_LOCALLOC_ALIGNMENT - 1)); code = mono_emit_stack_alloc (cfg, code, ins); x86_mov_reg_reg (code, ins->dreg, X86_ESP, 4); - if (cfg->param_area && cfg->arch.no_pushes) - x86_alu_reg_imm (code, X86_ADD, ins->dreg, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); + if (cfg->param_area) + x86_alu_reg_imm (code, X86_ADD, ins->dreg, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); break; case OP_LOCALLOC_IMM: { guint32 size = ins->inst_imm; @@ -3478,8 +3330,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) x86_alu_reg_imm (code, X86_SUB, X86_ESP, size); x86_mov_reg_reg (code, ins->dreg, X86_ESP, 4); } - if (cfg->param_area && cfg->arch.no_pushes) - x86_alu_reg_imm (code, X86_ADD, ins->dreg, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); + if (cfg->param_area) + x86_alu_reg_imm (code, X86_ADD, ins->dreg, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); break; } case OP_THROW: { @@ -3510,9 +3362,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_START_HANDLER: { MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region); x86_mov_membase_reg (code, spvar->inst_basereg, spvar->inst_offset, X86_ESP, 4); - if (cfg->param_area && cfg->arch.no_pushes) { + if (cfg->param_area) x86_alu_reg_imm (code, X86_SUB, X86_ESP, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); - } break; } case OP_ENDFINALLY: { @@ -5337,10 +5188,8 @@ mono_arch_emit_prolog (MonoCompile *cfg) cfg->frame_reg = X86_ESP; } - if (cfg->arch.no_pushes) { - cfg->stack_offset += cfg->param_area; - cfg->stack_offset = ALIGN_TO (cfg->stack_offset, MONO_ARCH_FRAME_ALIGNMENT); - } + cfg->stack_offset += cfg->param_area; + cfg->stack_offset = ALIGN_TO (cfg->stack_offset, MONO_ARCH_FRAME_ALIGNMENT); alloc_size = cfg->stack_offset; pos = 0; @@ -5820,8 +5669,6 @@ mono_arch_free_jit_tls_data (MonoJitTlsData *tls) { } -#ifdef MONO_ARCH_HAVE_IMT - // Linear handler, the bsearch head compare is shorter //[2 + 4] x86_alu_reg_imm (code, X86_CMP, ins->sreg1, ins->inst_imm); //[1 + 1] x86_branch8(inst,cond,imm,is_signed) @@ -5990,7 +5837,6 @@ mono_arch_find_imt_method (mgreg_t *regs, guint8 *code) { return (MonoMethod*) regs [MONO_ARCH_IMT_REG]; } -#endif MonoVTable* mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code) @@ -6183,10 +6029,8 @@ mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code) * The stack looks like: * * - * - * <4 pointers pushed by mono_arch_create_trampoline_code ()> */ - res = (((MonoObject**)esp) [5 + (offset / 4)]); + res = ((MonoObject**)esp) [0]; if (cinfo) g_free (cinfo); return res; @@ -6257,8 +6101,7 @@ get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *cod g_assert ((code - start) < code_reserve); } - nacl_global_codeman_validate(&start, code_reserve, &code); - mono_debug_add_delegate_trampoline (start, code - start); + nacl_global_codeman_validate (&start, code_reserve, &code); if (code_len) *code_len = code - start; @@ -6358,6 +6201,36 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe return start; } +gpointer +mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg) +{ + guint8 *code, *start; + int size = 24; + + /* + * The stack contains: + * + * + */ + start = code = mono_global_codeman_reserve (size); + + /* Replace the this argument with the target */ + x86_mov_reg_membase (code, X86_EAX, X86_ESP, 4, 4); + x86_mov_reg_membase (code, X86_ECX, X86_EAX, MONO_STRUCT_OFFSET (MonoDelegate, target), 4); + x86_mov_membase_reg (code, X86_ESP, 4, X86_ECX, 4); + + if (load_imt_reg) { + /* Load the IMT reg */ + x86_mov_reg_membase (code, MONO_ARCH_IMT_REG, X86_EAX, MONO_STRUCT_OFFSET (MonoDelegate, method), 4); + } + + /* Load the vtable */ + x86_mov_reg_membase (code, X86_EAX, X86_ECX, MONO_STRUCT_OFFSET (MonoObject, vtable), 4); + x86_jump_membase (code, X86_EAX, offset); + + return start; +} + mgreg_t mono_arch_context_get_int_reg (MonoContext *ctx, int reg) {