X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-ia64.c;h=c45305e2668a99e960a45797daec97f6011df4a3;hb=d0b97d4bd5f42978987b4ae1d7cad18bedd3b393;hp=556118dd14688281df38ff2b4fea6d7c3a0e54e6;hpb=6f5a0b555436eba699f9dd2659471044097b951b;p=mono.git diff --git a/mono/mini/mini-ia64.c b/mono/mini/mini-ia64.c index 556118dd146..c45305e2668 100644 --- a/mono/mini/mini-ia64.c +++ b/mono/mini/mini-ia64.c @@ -28,9 +28,6 @@ #include "jit-icalls.h" #include "ir-emit.h" -static gint appdomain_tls_offset = -1; -static gint thread_tls_offset = -1; - #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) #define IS_IMM32(val) ((((guint64)val) >> 32) == 0) @@ -112,33 +109,11 @@ mono_arch_fregname (int reg) return "unknown"; } -G_GNUC_UNUSED static void -break_count (void) -{ -} - -G_GNUC_UNUSED static gboolean -debug_count (void) -{ - static int count = 0; - count ++; - - if (count == atoi (getenv ("COUNT"))) { - break_count (); - } - - if (count > atoi (getenv ("COUNT"))) { - return FALSE; - } - - return TRUE; -} - static gboolean debug_ins_sched (void) { #if 0 - return debug_count (); + return mono_debug_count (); #else return TRUE; #endif @@ -148,7 +123,7 @@ static gboolean debug_omit_fp (void) { #if 0 - return debug_count (); + return mono_debug_count (); #else return TRUE; #endif @@ -191,6 +166,9 @@ typedef struct { guint32 reg_usage; guint32 freg_usage; gboolean need_stack_align; + gboolean vtype_retaddr; + /* The index of the vret arg in the argument list */ + int vret_arg_index; ArgInfo ret; ArgInfo sig_cookie; ArgInfo args [1]; @@ -353,7 +331,7 @@ add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgIn static CallInfo* get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke) { - guint32 i, gr, fr; + guint32 i, gr, fr, pstart; MonoType *ret_type; int n = sig->hasthis + sig->param_count; guint32 stack_size = 0; @@ -404,7 +382,7 @@ get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboo cinfo->ret.reg = 8; break; case MONO_TYPE_GENERICINST: - if (!mono_type_generic_inst_is_valuetype (sig->ret)) { + if (!mono_type_generic_inst_is_valuetype (ret_type)) { cinfo->ret.storage = ArgInIReg; cinfo->ret.reg = IA64_R8; break; @@ -419,11 +397,10 @@ get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboo cinfo->ret.storage = ArgInIReg; } else { add_valuetype (gsctx, sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize); - if (cinfo->ret.storage == ArgOnStack) + if (cinfo->ret.storage == ArgOnStack) { /* The caller passes the address where the value is stored */ - add_general (&gr, &stack_size, &cinfo->ret); - if (cinfo->ret.storage == ArgInIReg) - cinfo->ret.storage = ArgValuetypeAddrInIReg; + cinfo->vtype_retaddr = TRUE; + } } break; } @@ -435,9 +412,36 @@ get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboo } } - /* this */ - if (sig->hasthis) - add_general (&gr, &stack_size, cinfo->args + 0); + pstart = 0; + /* + * To simplify get_this_arg_reg () and LLVM integration, emit the vret arg after + * the first argument, allowing 'this' to be always passed in the first arg reg. + * Also do this if the first argument is a reference type, since virtual calls + * are sometimes made using calli without sig->hasthis set, like in the delegate + * invoke wrappers. + */ + if (cinfo->vtype_retaddr && !is_pinvoke && (sig->hasthis || (sig->param_count > 0 && MONO_TYPE_IS_REFERENCE (mini_type_get_underlying_type (gsctx, sig->params [0]))))) { + if (sig->hasthis) { + add_general (&gr, &stack_size, cinfo->args + 0); + } else { + add_general (&gr, &stack_size, &cinfo->args [sig->hasthis + 0]); + pstart = 1; + } + add_general (&gr, &stack_size, &cinfo->ret); + if (cinfo->ret.storage == ArgInIReg) + cinfo->ret.storage = ArgValuetypeAddrInIReg; + cinfo->vret_arg_index = 1; + } else { + /* this */ + if (sig->hasthis) + add_general (&gr, &stack_size, cinfo->args + 0); + + if (cinfo->vtype_retaddr) { + add_general (&gr, &stack_size, &cinfo->ret); + if (cinfo->ret.storage == ArgInIReg) + cinfo->ret.storage = ArgValuetypeAddrInIReg; + } + } if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (n == 0)) { gr = PARAM_REGS; @@ -447,7 +451,7 @@ get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboo add_general (&gr, &stack_size, &cinfo->sig_cookie); } - for (i = 0; i < sig->param_count; ++i) { + for (i = pstart; i < sig->param_count; ++i) { ArgInfo *ainfo = &cinfo->args [sig->hasthis + i]; MonoType *ptype; @@ -497,7 +501,7 @@ get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboo add_general (&gr, &stack_size, ainfo); break; case MONO_TYPE_GENERICINST: - if (!mono_type_generic_inst_is_valuetype (sig->params [i])) { + if (!mono_type_generic_inst_is_valuetype (ptype)) { add_general (&gr, &stack_size, ainfo); break; } @@ -549,7 +553,7 @@ get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboo * Returns the size of the argument area on the stack. */ 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; CallInfo *cinfo = get_call_info (NULL, NULL, csig, FALSE); @@ -599,13 +603,26 @@ mono_arch_cleanup (void) * This function returns the optimizations supported on this cpu. */ guint32 -mono_arch_cpu_optimizazions (guint32 *exclude_mask) +mono_arch_cpu_optimizations (guint32 *exclude_mask) { *exclude_mask = 0; return 0; } +/* + * 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; +} + GList * mono_arch_get_allocatable_int_vars (MonoCompile *cfg) { @@ -615,7 +632,7 @@ mono_arch_get_allocatable_int_vars (MonoCompile *cfg) MonoMethodHeader *header; CallInfo *cinfo; - header = mono_method_get_header (cfg->method); + header = cfg->header; sig = mono_method_signature (cfg->method); @@ -673,7 +690,7 @@ mono_ia64_alloc_stacked_registers (MonoCompile *cfg) cinfo = get_call_info (cfg, cfg->mempool, mono_method_signature (cfg->method), FALSE); - header = mono_method_get_header (cfg->method); + header = cfg->header; /* Some registers are reserved for use by the prolog/epilog */ reserved_regs = header->num_clauses ? 4 : 3; @@ -759,7 +776,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) gint32 *offsets; CallInfo *cinfo; - header = mono_method_get_header (cfg->method); + header = cfg->header; sig = mono_method_signature (cfg->method); @@ -849,7 +866,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) } /* Allocate locals */ - offsets = mono_allocate_stack_slots_full (cfg, cfg->arch.omit_fp ? FALSE : TRUE, &locals_stack_size, &locals_stack_align); + offsets = mono_allocate_stack_slots (cfg, cfg->arch.omit_fp ? FALSE : TRUE, &locals_stack_size, &locals_stack_align); if (locals_stack_align) { offset = ALIGN_TO (offset, locals_stack_align); } @@ -1594,7 +1611,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) /* Branch opts can eliminate the branch */ if (!next || (!(MONO_IS_COND_BRANCH_OP (next) || MONO_IS_COND_EXC (next) || MONO_IS_SETCC (next)))) { - ins->opcode = OP_NOP; + NULLIFY_INS (ins); break; } @@ -1630,8 +1647,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) if (MONO_IS_COND_BRANCH_OP (next)) { next->opcode = OP_IA64_BR_COND; - if (! (next->flags & MONO_INST_BRLABEL)) - next->inst_target_bb = next->inst_true_bb; + next->inst_target_bb = next->inst_true_bb; } else if (MONO_IS_COND_EXC (next)) { next->opcode = OP_IA64_COND_EXC; } else if (MONO_IS_SETCC (next)) { @@ -1653,7 +1669,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) /* Branch opts can eliminate the branch */ if (!next || (!(MONO_IS_COND_BRANCH_OP (next) || MONO_IS_COND_EXC (next) || MONO_IS_SETCC (next)))) { - ins->opcode = OP_NOP; + NULLIFY_INS (ins); break; } @@ -1661,8 +1677,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) if (MONO_IS_COND_BRANCH_OP (next)) { next->opcode = OP_IA64_BR_COND; - if (! (next->flags & MONO_INST_BRLABEL)) - next->inst_target_bb = next->inst_true_bb; + next->inst_target_bb = next->inst_true_bb; } else if (MONO_IS_COND_EXC (next)) { next->opcode = OP_IA64_COND_EXC; } else if (MONO_IS_SETCC (next)) { @@ -1685,6 +1700,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) temp->sreg2 = ins->sreg2; ins->opcode = OP_IA64_CSET; + MONO_INST_NULLIFY_SREGS (ins); break; case OP_MUL_IMM: case OP_LMUL_IMM: @@ -2045,7 +2061,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) cfg->code_size *= 2; cfg->native_code = g_realloc (cfg->native_code, cfg->code_size); code_start = cfg->native_code + offset; - mono_jit_stats.code_reallocs++; + cfg->stat_code_reallocs++; ia64_codegen_init (code, code_start); } @@ -2072,25 +2088,16 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) int pred = 0; if (ins->opcode == OP_IA64_BR_COND) pred = 6; - if (ins->flags & MONO_INST_BRLABEL) { - if (ins->inst_i0->inst_c0) { - NOT_IMPLEMENTED; - } else { - add_patch_info (cfg, code, MONO_PATCH_INFO_LABEL, ins->inst_i0); - ia64_br_cond_pred (code, pred, 0); - } - } else { - if (ins->inst_target_bb->native_offset) { - guint8 *pos = code.buf + code.nins; + if (ins->inst_target_bb->native_offset) { + guint8 *pos = code.buf + code.nins; - ia64_br_cond_pred (code, pred, 0); - ia64_begin_bundle (code); - ia64_patch (pos, cfg->native_code + ins->inst_target_bb->native_offset); - } else { - add_patch_info (cfg, code, MONO_PATCH_INFO_BB, ins->inst_target_bb); - ia64_br_cond_pred (code, pred, 0); - } - } + ia64_br_cond_pred (code, pred, 0); + ia64_begin_bundle (code); + ia64_patch (pos, cfg->native_code + ins->inst_target_bb->native_offset); + } else { + add_patch_info (cfg, code, MONO_PATCH_INFO_BB, ins->inst_target_bb); + ia64_br_cond_pred (code, pred, 0); + } break; } case OP_LABEL: @@ -2141,6 +2148,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ia64_shl (code, ins->dreg, ins->sreg1, ins->sreg2); break; case OP_ISHR: + ia64_sxt4 (code, GP_SCRATCH_REG, ins->sreg1); + ia64_shr (code, ins->dreg, GP_SCRATCH_REG, ins->sreg2); + break; case OP_LSHR: ia64_shr (code, ins->dreg, ins->sreg1, ins->sreg2); break; @@ -2240,10 +2250,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ia64_shl_imm (code, ins->dreg, ins->sreg1, ins->inst_imm); break; case OP_SHR_IMM: - case OP_ISHR_IMM: case OP_LSHR_IMM: ia64_shr_imm (code, ins->dreg, ins->sreg1, ins->inst_imm); break; + case OP_ISHR_IMM: + g_assert (ins->inst_imm <= 64); + ia64_extr (code, ins->dreg, ins->sreg1, ins->inst_imm, 32 - ins->inst_imm); + break; case OP_ISHR_UN_IMM: ia64_zxt4 (code, GP_SCRATCH_REG, ins->sreg1); ia64_shr_u_imm (code, ins->dreg, GP_SCRATCH_REG, ins->inst_imm); @@ -2693,7 +2706,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* Calls */ case OP_CHECK_THIS: /* ensure ins->sreg1 is not NULL */ - ia64_ld8 (code, GP_SCRATCH_REG, ins->sreg1); + /* Can't use ld8 as this could be a vtype address */ + ia64_ld1 (code, GP_SCRATCH_REG, ins->sreg1); break; case OP_ARGLIST: ia64_adds_imm (code, GP_SCRATCH_REG, cfg->sig_cookie, cfg->frame_reg); @@ -2726,13 +2740,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) int out_reg; /* - * mono_arch_find_this_arg () needs to find the this argument in a global + * mono_arch_get_this_arg_from_call () needs to find the this argument in a global * register. */ cinfo = get_call_info (cfg, cfg->mempool, call->signature, FALSE); out_reg = cfg->arch.reg_out0; - if (cinfo->ret.storage == ArgValuetypeAddrInIReg) - out_reg ++; ia64_mov (code, IA64_R10, out_reg); /* Indirect call */ @@ -2755,12 +2767,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) CallInfo *cinfo; int out_reg; - /* - * There are no membase instructions on ia64, but we can't - * lower this since get_vcall_slot_addr () needs to decode it. - */ - - /* Keep this in synch with get_vcall_slot_addr */ ia64_mov (code, IA64_R11, ins->sreg1); if (ia64_is_imm14 (ins->inst_offset)) ia64_adds_imm (code, IA64_R8, ins->inst_offset, ins->sreg1); @@ -2784,27 +2790,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) */ cinfo = get_call_info (cfg, cfg->mempool, call->signature, FALSE); out_reg = cfg->arch.reg_out0; - if (cinfo->ret.storage == ArgValuetypeAddrInIReg) - out_reg ++; ia64_mov (code, IA64_R10, out_reg); - ia64_begin_bundle (code); - ia64_codegen_set_one_ins_per_bundle (code, TRUE); - ia64_ld8 (code, GP_SCRATCH_REG, IA64_R8); ia64_mov_to_br (code, IA64_B6, GP_SCRATCH_REG); - /* - * This nop will tell get_vcall_slot_addr that this is a virtual - * call. - */ - ia64_nop_i (code, 0x12345); - ia64_br_call_reg (code, IA64_B0, IA64_B6); - ia64_codegen_set_one_ins_per_bundle (code, FALSE); - code = emit_move_return_value (cfg, ins, code); break; } @@ -3014,6 +3007,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ia64_movl (code, GP_SCRATCH_REG2, 0); ia64_mov_to_br (code, IA64_B6, GP_SCRATCH_REG2); ia64_br_cond_reg (code, IA64_B6); + // FIXME: + //mono_cfg_add_try_hole (cfg, ins->inst_eh_block, code, bb); ia64_codegen_set_one_ins_per_bundle (code, FALSE); break; case OP_START_HANDLER: { @@ -3781,7 +3776,7 @@ ia64_patch (unsigned char* code, gpointer target) } void -mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gboolean run_cctors) +mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors) { MonoJumpInfo *patch_info; @@ -3816,7 +3811,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) cinfo = get_call_info (cfg, cfg->mempool, sig, FALSE); - cfg->code_size = MAX (((MonoMethodNormal *)method)->header->code_size * 4, 512); + cfg->code_size = MAX (cfg->header->code_size * 4, 512); if (mono_jit_trace_calls != NULL && mono_trace_eval (method)) cfg->code_size += 1024; @@ -4057,7 +4052,7 @@ mono_arch_emit_epilog (MonoCompile *cfg) while (cfg->code_len + max_epilog_size > cfg->code_size) { cfg->code_size *= 2; cfg->native_code = g_realloc (cfg->native_code, cfg->code_size); - mono_jit_stats.code_reallocs++; + cfg->stat_code_reallocs++; } /* FIXME: Emit unwind info */ @@ -4171,7 +4166,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg) while (cfg->code_len + code_size > (cfg->code_size - 16)) { cfg->code_size *= 2; cfg->native_code = g_realloc (cfg->native_code, cfg->code_size); - mono_jit_stats.code_reallocs++; + cfg->stat_code_reallocs++; } ia64_codegen_init (code, cfg->native_code + cfg->code_len); @@ -4365,7 +4360,7 @@ mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p, gboolean ena } void* -mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments) +mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments, gboolean preserve_argument_registers) { Ia64CodegenState code; CallInfo *cinfo = NULL; @@ -4512,94 +4507,17 @@ mono_arch_get_patch_offset (guint8 *code) return 0; } -gpointer -mono_arch_get_vcall_slot (guint8* code, gpointer *regs, int *displacement) -{ - guint8 *bundle2 = code - 48; - guint8 *bundle3 = code - 32; - guint8 *bundle4 = code - 16; - guint64 ins21 = ia64_bundle_ins1 (bundle2); - guint64 ins22 = ia64_bundle_ins2 (bundle2); - guint64 ins23 = ia64_bundle_ins3 (bundle2); - guint64 ins31 = ia64_bundle_ins1 (bundle3); - guint64 ins32 = ia64_bundle_ins2 (bundle3); - guint64 ins33 = ia64_bundle_ins3 (bundle3); - guint64 ins41 = ia64_bundle_ins1 (bundle4); - guint64 ins42 = ia64_bundle_ins2 (bundle4); - guint64 ins43 = ia64_bundle_ins3 (bundle4); - - /* - * Virtual calls are made with: - * - * [MII] ld8 r31=[r8] - * nop.i 0x0 - * nop.i 0x0;; - * [MII] nop.m 0x0 - * mov.sptk b6=r31,0x2000000000f32a80 - * nop.i 0x0 - * [MII] nop.m 0x0 - * nop.i 0x123456 - * nop.i 0x0 - * [MIB] nop.m 0x0 - * nop.i 0x0 - * br.call.sptk.few b0=b6;; - */ - - if (((ia64_bundle_template (bundle3) == IA64_TEMPLATE_MII) || - (ia64_bundle_template (bundle3) == IA64_TEMPLATE_MIIS)) && - (ia64_bundle_template (bundle4) == IA64_TEMPLATE_MIBS) && - (ins31 == IA64_NOP_M) && - (ia64_ins_opcode (ins32) == 0) && (ia64_ins_x3 (ins32) == 0) && (ia64_ins_x6 (ins32) == 0x1) && (ia64_ins_y (ins32) == 0) && - (ins33 == IA64_NOP_I) && - (ins41 == IA64_NOP_M) && - (ins42 == IA64_NOP_I) && - (ia64_ins_opcode (ins43) == 1) && (ia64_ins_b1 (ins43) == 0) && (ia64_ins_b2 (ins43) == 6) && - ((ins32 >> 6) & 0xfffff) == 0x12345) { - g_assert (ins21 == IA64_NOP_M); - g_assert (ins23 == IA64_NOP_I); - g_assert (ia64_ins_opcode (ins22) == 0); - g_assert (ia64_ins_x3 (ins22) == 7); - g_assert (ia64_ins_x (ins22) == 0); - g_assert (ia64_ins_b1 (ins22) == IA64_B6); - - *displacement = (gssize)regs [IA64_R8] - (gssize)regs [IA64_R11]; - - return regs [IA64_R11]; - } - - return NULL; -} - -gpointer* -mono_arch_get_vcall_slot_addr (guint8* code, gpointer *regs) -{ - gpointer vt; - int displacement; - vt = mono_arch_get_vcall_slot (code, regs, &displacement); - if (!vt) - return NULL; - return (gpointer*)(gpointer)((char*)vt + displacement); -} - gpointer* -mono_arch_get_delegate_method_ptr_addr (guint8* code, gpointer *regs) +mono_arch_get_delegate_method_ptr_addr (guint8* code, mgreg_t *regs) { NOT_IMPLEMENTED; return NULL; } -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; - - appdomain_tls_offset = mono_domain_get_tls_offset (); - thread_tls_offset = mono_thread_get_tls_offset (); - } } void @@ -4621,8 +4539,6 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI guint8 *start, *buf; Ia64CodegenState code; - g_assert (!fail_tramp); - size = count * 256; buf = g_malloc0 (size); ia64_codegen_init (code, buf); @@ -4634,18 +4550,33 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI ia64_begin_bundle (code); item->code_target = (guint8*)code.buf + code.nins; if (item->is_equals) { - if (item->check_target_idx) { - if (!item->compare_done) { + gboolean fail_case = !item->check_target_idx && fail_tramp; + + if (item->check_target_idx || fail_case) { + if (!item->compare_done || fail_case) { ia64_movl (code, GP_SCRATCH_REG, item->key); ia64_cmp_eq (code, 6, 7, IA64_R9, GP_SCRATCH_REG); } item->jmp_code = (guint8*)code.buf + code.nins; ia64_br_cond_pred (code, 7, 0); - ia64_movl (code, GP_SCRATCH_REG, &(vtable->vtable [item->value.vtable_slot])); - ia64_ld8 (code, GP_SCRATCH_REG, GP_SCRATCH_REG); + if (item->has_target_code) { + ia64_movl (code, GP_SCRATCH_REG, item->value.target_code); + } else { + ia64_movl (code, GP_SCRATCH_REG, &(vtable->vtable [item->value.vtable_slot])); + ia64_ld8 (code, GP_SCRATCH_REG, GP_SCRATCH_REG); + } ia64_mov_to_br (code, IA64_B6, GP_SCRATCH_REG); ia64_br_cond_reg (code, IA64_B6); + + if (fail_case) { + ia64_begin_bundle (code); + ia64_patch (item->jmp_code, (guint8*)code.buf + code.nins); + ia64_movl (code, GP_SCRATCH_REG, fail_tramp); + ia64_mov_to_br (code, IA64_B6, GP_SCRATCH_REG); + ia64_br_cond_reg (code, IA64_B6); + item->jmp_code = NULL; + } } else { /* enable the commented code to assert on wrong method */ #if ENABLE_WRONG_METHOD_CHECK @@ -4680,7 +4611,12 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI g_assert (code.buf - buf <= size); size = code.buf - buf; - start = mono_code_manager_reserve (domain->code_mp, size); + if (fail_tramp) { + start = mono_method_alloc_generic_virtual_thunk (domain, size + 16); + start = (gpointer)ALIGN_TO (start, 16); + } else { + start = mono_domain_code_reserve (domain, size); + } memcpy (start, buf, size); mono_arch_flush_icache (start, size); @@ -4691,9 +4627,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI } MonoMethod* -mono_arch_find_imt_method (gpointer *regs, guint8 *code) +mono_arch_find_imt_method (mgreg_t *regs, guint8 *code) { - return regs [IA64_R9]; + return (MonoMethod*)regs [IA64_R9]; } void @@ -4704,17 +4640,11 @@ mono_arch_emit_imt_argument (MonoCompile *cfg, MonoCallInst *call, MonoInst *imt #endif gpointer -mono_arch_get_this_arg_from_call (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gssize *regs, guint8 *code) +mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code) { return (gpointer)regs [IA64_R10]; } -MonoObject* -mono_arch_find_this_argument (gpointer *regs, MonoMethod *method, MonoGenericSharingContext *gsctx) -{ - return mono_arch_get_this_arg_from_call (gsctx, mono_method_signature (method), (gssize*)regs, NULL); -} - gpointer mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target) { @@ -4817,31 +4747,13 @@ mono_arch_print_tree (MonoInst *tree, int arity) return 0; } -MonoInst* mono_arch_get_domain_intrinsic (MonoCompile* cfg) -{ - MonoInst* ins; - - if (appdomain_tls_offset == -1) - return NULL; - - MONO_INST_NEW (cfg, ins, OP_TLS_GET); - ins->inst_offset = appdomain_tls_offset; - return ins; -} - -MonoInst* mono_arch_get_thread_intrinsic (MonoCompile* cfg) +MonoInst* +mono_arch_get_domain_intrinsic (MonoCompile* cfg) { - MonoInst* ins; - - if (thread_tls_offset == -1) - return NULL; - - MONO_INST_NEW (cfg, ins, OP_TLS_GET); - ins->inst_offset = thread_tls_offset; - return ins; + return mono_get_domain_intrinsic (cfg); } -gpointer +mgreg_t mono_arch_context_get_int_reg (MonoContext *ctx, int reg) { /* FIXME: implement */