X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-mips.c;h=fd0e074ecbbe6839ce2b1d72f3af2a8ef6ffa8d6;hb=1f5d985270df9390f9cb558656763ea428c14e2c;hp=8b20cb05b4ac743141c28242c7154f3fc3d76978;hpb=2211e3a5d02ca546fdbad2033b8b3d0c817c97c3;p=mono.git diff --git a/mono/mini/mini-mips.c b/mono/mini/mini-mips.c index 8b20cb05b4a..fd0e074ecbb 100644 --- a/mono/mini/mini-mips.c +++ b/mono/mini/mini-mips.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -56,15 +57,14 @@ enum { }; /* 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_os_mutex_lock (&mini_arch_mutex) +#define mono_mini_arch_unlock() mono_os_mutex_unlock (&mini_arch_mutex) +static mono_mutex_t mini_arch_mutex; int mono_exc_esp_offset = 0; static int tls_mode = TLS_MODE_DETECT; static int lmf_pthread_key = -1; static int monothread_key = -1; -static int monodomain_key = -1; /* Whenever the host is little-endian */ static int little_endian; @@ -497,7 +497,7 @@ emit_memcpy (guint8 *code, int size, int dreg, int doffset, int sreg, int soffse * Returns the size of the activation frame. */ int -mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info) +mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info) { int k, frame_size = 0; guint32 size, align, pad; @@ -518,7 +518,7 @@ mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignatu arg_info [0].size = frame_size; for (k = 0; k < param_count; k++) { - size = mini_type_stack_size_full (NULL, csig->params [k], &align, csig->pinvoke); + size = mini_type_stack_size_full (csig->params [k], &align, csig->pinvoke); /* ignore alignment for now */ align = 1; @@ -544,7 +544,7 @@ mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignatu #define MAX_ARCH_DELEGATE_PARAMS (4 - 1) static gpointer -get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *code_size) +get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, gboolean param_count) { guint8 *code, *start; @@ -552,8 +552,8 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co start = code = mono_global_codeman_reserve (16); /* Replace the this argument with the target */ - mips_lw (code, mips_temp, mips_a0, G_STRUCT_OFFSET (MonoDelegate, method_ptr)); - mips_lw (code, mips_a0, mips_a0, G_STRUCT_OFFSET (MonoDelegate, target)); + mips_lw (code, mips_temp, mips_a0, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr)); + mips_lw (code, mips_a0, mips_a0, MONO_STRUCT_OFFSET (MonoDelegate, target)); mips_jr (code, mips_temp); mips_nop (code); @@ -566,7 +566,7 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co size = 16 + param_count * 4; start = code = mono_global_codeman_reserve (size); - mips_lw (code, mips_temp, mips_a0, G_STRUCT_OFFSET (MonoDelegate, method_ptr)); + mips_lw (code, mips_temp, mips_a0, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr)); /* slide down the arguments */ for (i = 0; i < param_count; ++i) { mips_move (code, mips_a0 + i, mips_a0 + i + 1); @@ -579,8 +579,13 @@ get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *co mono_arch_flush_icache (start, size); } - if (code_size) - *code_size = code - start; + if (has_target) { + *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, NULL); + } else { + char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count); + *info = mono_tramp_info_create (name, start, code - start, NULL, NULL); + g_free (name); + } return start; } @@ -595,19 +600,15 @@ GSList* mono_arch_get_delegate_invoke_impls (void) { GSList *res = NULL; - guint8 *code; - guint32 code_len; + MonoTrampInfo *info; int i; - char *tramp_name; - code = get_delegate_invoke_impl (TRUE, 0, &code_len); - res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL)); + get_delegate_invoke_impl (&info, TRUE, 0); + res = g_slist_prepend (res, info); for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) { - code = get_delegate_invoke_impl (FALSE, i, &code_len); - tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i); - res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL)); - g_free (tramp_name); + get_delegate_invoke_impl (&info, FALSE, i); + res = g_slist_prepend (res, info); } return res; @@ -630,10 +631,13 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe return cached; } - if (mono_aot_only) + if (mono_aot_only) { start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target"); - else - start = get_delegate_invoke_impl (TRUE, 0, NULL); + } else { + MonoTrampInfo *info; + start = get_delegate_invoke_impl (&info, TRUE, 0); + mono_tramp_info_register (info, NULL); + } cached = start; mono_mini_arch_unlock (); return cached; @@ -659,7 +663,9 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe start = mono_aot_get_trampoline (name); g_free (name); } else { - start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL); + MonoTrampInfo *info; + start = get_delegate_invoke_impl (&info, FALSE, sig->param_count); + mono_tramp_info_register (info, NULL); } cache [sig->param_count] = start; mono_mini_arch_unlock (); @@ -669,6 +675,12 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe return NULL; } +gpointer +mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg) +{ + return NULL; +} + gpointer mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code) { @@ -701,7 +713,7 @@ mono_arch_cpu_init (void) void mono_arch_init (void) { - InitializeCriticalSection (&mini_arch_mutex); + mono_os_mutex_init_recursive (&mini_arch_mutex); ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT); bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT); @@ -714,7 +726,7 @@ mono_arch_init (void) void mono_arch_cleanup (void) { - DeleteCriticalSection (&mini_arch_mutex); + mono_os_mutex_destroy (&mini_arch_mutex); } /* @@ -1048,7 +1060,7 @@ add_float64_arg (CallInfo *info, ArgInfo *ainfo) { #endif static CallInfo* -get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSignature *sig) +get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) { guint i; int n = sig->hasthis + sig->param_count; @@ -1090,7 +1102,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign * 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 (cinfo->vtype_retaddr && !is_pinvoke && (sig->hasthis || (sig->param_count > 0 && MONO_TYPE_IS_REFERENCE (mini_get_underlying_type (sig->params [0]))))) { if (sig->hasthis) { add_int32_arg (cinfo, cinfo->args + n); n ++; @@ -1125,7 +1137,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign add_int32_arg (cinfo, &cinfo->sig_cookie); } DEBUG(printf("param %d: ", i)); - simpletype = mini_type_get_underlying_type (gsctx, sig->params [i]); + simpletype = mini_get_underlying_type (sig->params [i]); switch (simpletype->type) { case MONO_TYPE_BOOLEAN: case MONO_TYPE_I1: @@ -1272,7 +1284,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign } { - simpletype = mini_type_get_underlying_type (gsctx, sig->ret); + simpletype = mini_get_underlying_type (sig->ret); switch (simpletype->type) { case MONO_TYPE_BOOLEAN: case MONO_TYPE_I1: @@ -1356,7 +1368,7 @@ mono_arch_compute_omit_fp (MonoCompile *cfg) sig = mono_method_signature (cfg->method); if (!cfg->arch.cinfo) - cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig); + cfg->arch.cinfo = get_call_info (cfg->mempool, sig); cinfo = cfg->arch.cinfo; /* @@ -1421,7 +1433,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) sig = mono_method_signature (cfg->method); if (!cfg->arch.cinfo) - cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig); + cfg->arch.cinfo = get_call_info (cfg->mempool, sig); cinfo = cfg->arch.cinfo; mono_arch_compute_omit_fp (cfg); @@ -1464,7 +1476,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) curinst = 0; if (!MONO_TYPE_ISSTRUCT (sig->ret)) { /* FIXME: handle long and FP values */ - switch (mini_type_get_underlying_type (cfg->generic_sharing_context, sig->ret)->type) { + switch (mini_get_underlying_type (sig->ret)->type) { case MONO_TYPE_VOID: break; case MONO_TYPE_R4: @@ -1699,7 +1711,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) sig = call->signature; n = sig->param_count + sig->hasthis; - cinfo = get_call_info (NULL, cfg->mempool, sig); + cinfo = get_call_info (cfg->mempool, sig); if (cinfo->struct_ret) call->used_iregs |= 1 << cinfo->struct_ret; @@ -1711,7 +1723,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) t = sig->params [i - sig->hasthis]; else t = &mono_defaults.int_class->byval_arg; - t = mini_type_get_underlying_type (cfg->generic_sharing_context, t); + t = mini_get_underlying_type (t); if ((sig->call_convention == MONO_CALL_VARARG) && (i == sig->sentinelpos)) { /* Emit the signature cookie just before the implicit arguments */ @@ -1730,13 +1742,13 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) if (!t->byref && ((t->type == MONO_TYPE_I8) || (t->type == MONO_TYPE_U8))) { MONO_INST_NEW (cfg, ins, OP_MOVE); ins->dreg = mono_alloc_ireg (cfg); - ins->sreg1 = in->dreg + 1; + ins->sreg1 = MONO_LVREG_LS (in->dreg); MONO_ADD_INS (cfg->cbb, ins); mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg + ls_word_idx, FALSE); MONO_INST_NEW (cfg, ins, OP_MOVE); ins->dreg = mono_alloc_ireg (cfg); - ins->sreg1 = in->dreg + 2; + ins->sreg1 = MONO_LVREG_MS (in->dreg); MONO_ADD_INS (cfg->cbb, ins); mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg + ms_word_idx, FALSE); } else @@ -1929,7 +1941,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src) size = mono_type_native_stack_size (&src->klass->byval_arg, NULL); vtcopy->backend.is_pinvoke = 1; } else { - size = mini_type_stack_size (cfg->generic_sharing_context, &src->klass->byval_arg, NULL); + size = mini_type_stack_size (&src->klass->byval_arg, NULL); } if (size > 0) g_assert (ovf_size > 0); @@ -1947,8 +1959,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src) void mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val) { - MonoType *ret = mini_type_get_underlying_type (cfg->generic_sharing_context, - mono_method_signature (method)->ret); + MonoType *ret = mini_get_underlying_type (mono_method_signature (method)->ret); if (!ret->byref) { #if (SIZEOF_REGISTER == 4) @@ -1956,8 +1967,8 @@ mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val) MonoInst *ins; MONO_INST_NEW (cfg, ins, OP_SETLRET); - ins->sreg1 = val->dreg + 1; - ins->sreg2 = val->dreg + 2; + ins->sreg1 = MONO_LVREG_LS (val->dreg); + ins->sreg2 = MONO_LVREG_MS (val->dreg); MONO_ADD_INS (cfg->cbb, ins); return; } @@ -2605,6 +2616,8 @@ map_to_reg_reg_op (int op) case OP_STOREI8_MEMBASE_IMM: return OP_STOREI8_MEMBASE_REG; } + if (mono_op_imm_to_op (op) == -1) + g_error ("mono_op_imm_to_op failed for %s\n", mono_inst_name (op)); return mono_op_imm_to_op (op); } @@ -3204,7 +3217,7 @@ emit_load_volatile_arguments(MonoCompile *cfg, guint8 *code) sig = mono_method_signature (method); if (!cfg->arch.cinfo) - cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig); + cfg->arch.cinfo = get_call_info (cfg->mempool, sig); cinfo = cfg->arch.cinfo; if (cinfo->struct_ret) { @@ -3299,8 +3312,8 @@ emit_reserve_param_area (MonoCompile *cfg, guint8 *code) if (ppc_is_imm16 (-size)) { ppc_stwu (code, ppc_r0, -size, ppc_sp); } else { - ppc_load (code, ppc_r11, -size); - ppc_stwux (code, ppc_r0, ppc_sp, ppc_r11); + ppc_load (code, ppc_r12, -size); + ppc_stwux (code, ppc_r0, ppc_sp, ppc_r12); } #endif return code; @@ -3321,8 +3334,8 @@ emit_unreserve_param_area (MonoCompile *cfg, guint8 *code) if (ppc_is_imm16 (size)) { ppc_stwu (code, ppc_r0, size, ppc_sp); } else { - ppc_load (code, ppc_r11, size); - ppc_stwux (code, ppc_r0, ppc_sp, ppc_r11); + ppc_load (code, ppc_r12, size); + ppc_stwux (code, ppc_r0, ppc_sp, ppc_r12); } #endif return code; @@ -3388,6 +3401,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_NOT_REACHED: case OP_NOT_NULL: break; + case OP_IL_SEQ_POINT: + mono_add_seq_point (cfg, bb, ins, code - cfg->native_code); + break; case OP_SEQ_POINT: { if (ins->flags & MONO_INST_SINGLE_STEP_LOC) { guint32 addr = (guint32)ss_trigger_page; @@ -3425,9 +3441,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mips_mfhi (code, ins->dreg+1); break; case OP_MEMORY_BARRIER: -#if 0 - ppc_sync (code); -#endif + mips_sync (code, 0); break; case OP_STOREI1_MEMBASE_IMM: mips_load_const (code, mips_temp, ins->inst_imm); @@ -3713,8 +3727,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_DIV_IMM: g_assert_not_reached (); #if 0 - ppc_load (code, ppc_r11, ins->inst_imm); - ppc_divwod (code, ins->dreg, ins->sreg1, ppc_r11); + ppc_load (code, ppc_r12, ins->inst_imm); + ppc_divwod (code, ins->dreg, ins->sreg1, ppc_r12); ppc_mfspr (code, ppc_r0, ppc_xer); ppc_andisd (code, ppc_r0, ppc_r0, (1<<14)); /* FIXME: use OverflowException for 0x80000000/-1 */ @@ -3906,6 +3920,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mips_fmovd (code, ins->dreg, ins->sreg1); } break; + case OP_MOVE_F_TO_I4: + mips_cvtsd (code, mips_ftemp, ins->sreg1); + mips_mfc1 (code, ins->dreg, mips_ftemp); + break; + case OP_MOVE_I4_TO_F: + mips_mtc1 (code, ins->dreg, ins->sreg1); + mips_cvtds (code, ins->dreg, ins->dreg); + break; case OP_MIPS_CVTSD: /* Convert from double to float and leave it there */ mips_cvtsd (code, ins->dreg, ins->sreg1); @@ -4620,6 +4642,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_c1, ins->inst_p0); mips_load (code, ins->dreg, 0x0f0f0f0f); break; + case OP_GC_SAFE_POINT: + break; default: @@ -4648,7 +4672,7 @@ mono_arch_register_lowlevel_calls (void) } void -mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors) +mono_arch_patch_code (MonoCompile *cfg, MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gboolean run_cctors) { MonoJumpInfo *patch_info; @@ -5086,7 +5110,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) pos = 0; if (!cfg->arch.cinfo) - cfg->arch.cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig); + cfg->arch.cinfo = get_call_info (cfg->mempool, sig); cinfo = cfg->arch.cinfo; if (MONO_TYPE_ISSTRUCT (sig->ret)) { @@ -5325,7 +5349,7 @@ mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolea int save_mode = SAVE_NONE; int offset; MonoMethod *method = cfg->method; - int rtype = mini_type_get_underlying_type (cfg->generic_sharing_context, mono_method_signature (method)->ret)->type; + int rtype = mini_get_underlying_type (mono_method_signature (method)->ret)->type; int save_offset = MIPS_STACK_PARAM_OFFSET; g_assert ((save_offset & (MIPS_STACK_ALIGNMENT-1)) == 0); @@ -5756,11 +5780,6 @@ setup_tls_access (void) } #endif } - if (monodomain_key == -1) { - ptk = mono_domain_get_tls_key (); - if (ptk < 1024) - monodomain_key = ptk; - } if (lmf_pthread_key == -1) { ptk = mono_jit_tls_id; if (ptk < 1024) { @@ -5804,13 +5823,13 @@ mono_arch_emit_this_vret_args (MonoCompile *cfg, MonoCallInst *inst, int this_re /* add the this argument */ if (this_reg != -1) { - MonoInst *this; - MONO_INST_NEW (cfg, this, OP_MOVE); - this->type = this_type; - this->sreg1 = this_reg; - this->dreg = mono_alloc_ireg (cfg); - mono_bblock_add_inst (cfg->cbb, this); - mono_call_inst_add_outarg_reg (cfg, inst, this->dreg, this_dreg, FALSE); + MonoInst *this_ins; + MONO_INST_NEW (cfg, this_ins, OP_MOVE); + this_ins->type = this_type; + this_ins->sreg1 = this_reg; + this_ins->dreg = mono_alloc_ireg (cfg); + mono_bblock_add_inst (cfg->cbb, this_ins); + mono_call_inst_add_outarg_reg (cfg, inst, this_ins->dreg, this_dreg, FALSE); } if (vt_reg != -1) { @@ -5844,27 +5863,12 @@ mono_arch_print_tree (MonoInst *tree, int arity) return 0; } -MonoInst* mono_arch_get_domain_intrinsic (MonoCompile* cfg) -{ - MonoInst* ins; - - setup_tls_access (); - if (monodomain_key == -1) - return NULL; - - MONO_INST_NEW (cfg, ins, OP_TLS_GET); - ins->inst_offset = monodomain_key; - return ins; -} - mgreg_t mono_arch_context_get_int_reg (MonoContext *ctx, int reg) { return ctx->sc_regs [reg]; } -#ifdef MONO_ARCH_HAVE_IMT - #define ENABLE_WRONG_METHOD_CHECK 0 #define MIPS_LOAD_SEQUENCE_LENGTH 8 @@ -6010,6 +6014,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI mono_stats.imt_thunks_size += code - start; g_assert (code - start <= size); mono_arch_flush_icache (start, size); + + mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain); + return start; } @@ -6018,7 +6025,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) @@ -6161,3 +6167,9 @@ mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf) } #endif /* MONO_ARCH_SOFT_DEBUG_SUPPORTED */ + +gboolean +mono_arch_opcode_supported (int opcode) +{ + return FALSE; +}