X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-ppc.c;h=90240f63e5b6b31e228f6b16c0031290157b9057;hb=7c14046b9c9f7ba04459eb54db95eb8375a0031b;hp=d840db24857d0e3276c8dd3da3db3d2596468939;hpb=fe3cd6df05f6301c0f98f38348f423131c91fdbe;p=mono.git diff --git a/mono/mini/mini-ppc.c b/mono/mini/mini-ppc.c index d840db24857..90240f63e5b 100644 --- a/mono/mini/mini-ppc.c +++ b/mono/mini/mini-ppc.c @@ -341,6 +341,9 @@ is_load_sequence (guint32 *seq) #define ppc_load_get_off(l) ((gint16)((l) & 0xffff)) #endif +/* ld || lwz */ +#define ppc_is_load_op(opcode) (ppc_opcode ((opcode)) == 58 || ppc_opcode ((opcode)) == 32) + /* code must point to the blrl */ gboolean mono_ppc_is_direct_call_sequence (guint32 *code) @@ -350,12 +353,12 @@ mono_ppc_is_direct_call_sequence (guint32 *code) /* the thunk-less direct call sequence: lis/ori/sldi/oris/ori/mtlr/blrl */ if (ppc_opcode (code [-1]) == 31) { /* mtlr */ - if (ppc_opcode (code [-2]) == 58 && ppc_opcode (code [-3]) == 58) { /* ld/ld */ + if (ppc_is_load_op (code [-2]) && ppc_is_load_op (code [-3])) { /* ld/ld */ if (!is_load_sequence (&code [-8])) return FALSE; - /* one of the loads must be "ld r2,8(rX)" */ - return (ppc_load_get_dest (code [-2]) == ppc_r2 && ppc_load_get_off (code [-2]) == 8) || - (ppc_load_get_dest (code [-3]) == ppc_r2 && ppc_load_get_off (code [-3]) == 8); + /* one of the loads must be "ld r2,8(rX)" or "ld r2,4(rX) for ilp32 */ + return (ppc_load_get_dest (code [-2]) == ppc_r2 && ppc_load_get_off (code [-2]) == sizeof (gpointer)) || + (ppc_load_get_dest (code [-3]) == ppc_r2 && ppc_load_get_off (code [-3]) == sizeof (gpointer)); } if (ppc_opcode (code [-2]) == 24 && ppc_opcode (code [-3]) == 31) /* mr/nop */ return is_load_sequence (&code [-8]); @@ -373,53 +376,6 @@ mono_ppc_is_direct_call_sequence (guint32 *code) #endif } -gpointer -mono_arch_get_vcall_slot (guint8 *code_ptr, mgreg_t *regs, int *displacement) -{ - char *o = NULL; - int reg, offset = 0; - guint32* code = (guint32*)code_ptr; - mgreg_t *r = (mgreg_t*)regs; - - *displacement = 0; - - /* This is the 'blrl' instruction */ - --code; - - /* Sanity check: instruction must be 'blrl' */ - if (*code != 0x4e800021) - return NULL; - - if (mono_ppc_is_direct_call_sequence (code)) - return NULL; - - /* FIXME: more sanity checks here */ - /* OK, we're now at the 'blrl' instruction. Now walk backwards - till we get to a 'mtlr rA' */ - for (; --code;) { - if((*code & 0x7c0803a6) == 0x7c0803a6) { - gint16 soff; - /* Here we are: we reached the 'mtlr rA'. - Extract the register from the instruction */ - reg = (*code & 0x03e00000) >> 21; - --code; - /* ok, this is a lwz reg, offset (vtreg) - * it is emitted with: - * ppc_emit32 (c, (32 << 26) | ((D) << 21) | ((a) << 16) | (guint16)(d)) - */ - soff = (*code & 0xffff); - offset = soff; - reg = (*code >> 16) & 0x1f; - g_assert (reg != ppc_r1); - /*g_print ("patching reg is %d\n", reg);*/ - o = (gpointer)(gsize)r [reg]; - break; - } - } - *displacement = offset; - return o; -} - #define MAX_ARCH_DELEGATE_PARAMS 7 static gpointer @@ -488,11 +444,11 @@ mono_arch_get_delegate_invoke_impls (void) int i; code = get_delegate_invoke_impl (TRUE, 0, &code_len, TRUE); - res = g_slist_prepend (res, mono_aot_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len)); + res = g_slist_prepend (res, mono_tramp_info_create (g_strdup ("delegate_invoke_impl_has_target"), code, code_len, NULL, NULL)); for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) { code = get_delegate_invoke_impl (FALSE, i, &code_len, TRUE); - res = g_slist_prepend (res, mono_aot_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len)); + res = g_slist_prepend (res, mono_tramp_info_create (g_strdup_printf ("delegate_invoke_impl_target_%d", i), code, code_len, NULL, NULL)); } return res; @@ -514,7 +470,7 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe return cached; if (mono_aot_only) - start = mono_aot_get_named_code ("delegate_invoke_impl_has_target"); + start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target"); else start = get_delegate_invoke_impl (TRUE, 0, NULL, FALSE); @@ -538,7 +494,7 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe if (mono_aot_only) { char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", sig->param_count); - start = mono_aot_get_named_code (name); + start = mono_aot_get_trampoline (name); g_free (name); } else { start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL, FALSE); @@ -552,13 +508,10 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe } gpointer -mono_arch_get_this_arg_from_call (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, mgreg_t *regs, guint8 *code) +mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code) { mgreg_t *r = (mgreg_t*)regs; - /* FIXME: handle returning a struct */ - if (MONO_TYPE_ISSTRUCT (sig->ret)) - return (gpointer)(gsize)r [ppc_r4]; return (gpointer)(gsize)r [ppc_r3]; } @@ -611,7 +564,16 @@ linux_find_auxv (int *count) void mono_arch_cpu_init (void) { -#ifdef __APPLE__ +} + +/* + * Initialize architecture specific code. + */ +void +mono_arch_init (void) +{ +#if defined(MONO_CROSS_COMPILE) +#elif defined(__APPLE__) int mib [3]; size_t len; mib [0] = CTL_HW; @@ -665,7 +627,6 @@ mono_arch_cpu_init (void) #elif defined(G_COMPILER_CODEWARRIOR) cachelinesize = 32; cachelineinc = 32; -#elif defined(MONO_CROSS_COMPILE) #else //#error Need a way to get cache line size #endif @@ -676,19 +637,13 @@ mono_arch_cpu_init (void) if (mono_cpu_count () > 1) cpu_hw_caps |= PPC_SMP_CAPABLE; -} - -/* - * Initialize architecture specific code. - */ -void -mono_arch_init (void) -{ InitializeCriticalSection (&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); mono_mprotect (bp_trigger_page, mono_pagesize (), 0); + + mono_aot_register_jit_icall ("mono_ppc_throw_exception", mono_ppc_throw_exception); } /* @@ -752,6 +707,7 @@ is_regsize_var (MonoType *t) { return FALSE; } +#ifndef DISABLE_JIT GList * mono_arch_get_allocatable_int_vars (MonoCompile *cfg) { @@ -779,6 +735,7 @@ mono_arch_get_allocatable_int_vars (MonoCompile *cfg) return vars; } +#endif /* ifndef DISABLE_JIT */ GList * mono_arch_get_global_int_regs (MonoCompile *cfg) @@ -788,8 +745,14 @@ mono_arch_get_global_int_regs (MonoCompile *cfg) if (cfg->frame_reg != ppc_sp) top = 31; /* ppc_r13 is used by the system on PPC EABI */ - for (i = 14; i < top; ++i) - regs = g_list_prepend (regs, GUINT_TO_POINTER (i)); + for (i = 14; i < top; ++i) { + /* + * Reserve r29 for holding the vtable address for virtual calls in AOT mode, + * since the trampolines can clobber r11. + */ + if (!(cfg->compile_aot && i == 29)) + regs = g_list_prepend (regs, GUINT_TO_POINTER (i)); + } return regs; } @@ -929,6 +892,8 @@ typedef struct { guint32 struct_ret; ArgInfo ret; ArgInfo sig_cookie; + gboolean vtype_retaddr; + int vret_arg_index; ArgInfo args [1]; } CallInfo; @@ -996,9 +961,9 @@ has_only_a_r48_field (MonoClass *klass) #endif static CallInfo* -calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke) +calculate_sizes (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, gboolean is_pinvoke) { - guint i, fr, gr; + guint i, fr, gr, pstart; int n = sig->hasthis + sig->param_count; MonoType *simpletype; guint32 stack_size = 0; @@ -1009,17 +974,45 @@ calculate_sizes (MonoMethodSignature *sig, gboolean is_pinvoke) /* FIXME: handle returning a struct */ if (MONO_TYPE_ISSTRUCT (sig->ret)) { - add_general (&gr, &stack_size, &cinfo->ret, TRUE); - cinfo->struct_ret = PPC_FIRST_ARG_REG; + cinfo->vtype_retaddr = TRUE; } + pstart = 0; n = 0; - if (sig->hasthis) { - add_general (&gr, &stack_size, cinfo->args + n, TRUE); - n++; + /* + * 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, TRUE); + n ++; + } else { + add_general (&gr, &stack_size, &cinfo->args [sig->hasthis + 0], TRUE); + pstart = 1; + n ++; + } + add_general (&gr, &stack_size, &cinfo->ret, TRUE); + cinfo->struct_ret = cinfo->ret.reg; + cinfo->vret_arg_index = 1; + } else { + /* this */ + if (sig->hasthis) { + add_general (&gr, &stack_size, cinfo->args + 0, TRUE); + n ++; + } + + if (cinfo->vtype_retaddr) { + add_general (&gr, &stack_size, &cinfo->ret, TRUE); + cinfo->struct_ret = cinfo->ret.reg; + } } + DEBUG(printf("params: %d\n", sig->param_count)); - for (i = 0; i < sig->param_count; ++i) { + for (i = pstart; i < sig->param_count; ++i) { if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (i == sig->sentinelpos)) { /* Prevent implicit arguments and sig_cookie from being passed in registers */ @@ -1332,7 +1325,7 @@ mono_arch_allocate_vars (MonoCompile *m) if (m->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) m->param_area = MAX (m->param_area, sizeof (gpointer)*8); - header = mono_method_get_header (m->method); + header = m->header; /* * We use the frame register also for any method that has @@ -1469,6 +1462,11 @@ mono_arch_allocate_vars (MonoCompile *m) } if (MONO_TYPE_ISSTRUCT (sig->params [i]) && size < sizeof (gpointer)) size = align = sizeof (gpointer); + /* + * Use at least 4/8 byte alignment, since these might be passed in registers, and + * they are saved using std in the prolog. + */ + align = sizeof (gpointer); offset += align - 1; offset &= ~(align - 1); inst->inst_offset = offset; @@ -1491,7 +1489,7 @@ mono_arch_allocate_vars (MonoCompile *m) m->stack_offset = offset; if (sig->call_convention == MONO_CALL_VARARG) { - CallInfo *cinfo = calculate_sizes (m->method->signature, m->method->signature->pinvoke); + CallInfo *cinfo = calculate_sizes (m->generic_sharing_context, m->method->signature, m->method->signature->pinvoke); m->sig_cookie = cinfo->sig_cookie.offset; @@ -1537,7 +1535,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) sig = call->signature; n = sig->param_count + sig->hasthis; - cinfo = calculate_sizes (sig, sig->pinvoke); + cinfo = calculate_sizes (cfg->generic_sharing_context, sig, sig->pinvoke); for (i = 0; i < n; ++i) { ArgInfo *ainfo = cinfo->args + i; @@ -1664,6 +1662,8 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) g_free (cinfo); } +#ifndef DISABLE_JIT + void mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src) { @@ -1779,6 +1779,8 @@ mono_arch_is_inst_imm (gint64 imm) return TRUE; } +#endif /* DISABLE_JIT */ + /* * Allow tracing to work with this interface (with an optional argument) */ @@ -2148,7 +2150,11 @@ mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins) { switch (ins->opcode) { case OP_ICONV_TO_R_UN: { +#if G_BYTE_ORDER == G_BIG_ENDIAN static const guint64 adjust_val = 0x4330000000000000ULL; +#else + static const guint64 adjust_val = 0x0000000000003043ULL; +#endif int msw_reg = mono_alloc_ireg (cfg); int adj_reg = mono_alloc_freg (cfg); int tmp_reg = mono_alloc_freg (cfg); @@ -2266,12 +2272,9 @@ mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *ins) NULLIFY_INS (ins); break; case OP_LNEG: - /* This is the old version from inssel-long32.brg */ - MONO_EMIT_NEW_UNALU (cfg, OP_INOT, ins->dreg + 1, ins->sreg1 + 1); - MONO_EMIT_NEW_UNALU (cfg, OP_INOT, ins->dreg + 2, ins->sreg1 + 2); - /* ADC sets the condition codes */ - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ADC_IMM, ins->dreg + 1, ins->dreg + 1, 1); - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ADC_IMM, ins->dreg + 2, ins->dreg + 2, 0); + /* From gcc generated code */ + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_PPC_SUBFIC, ins->dreg + 1, ins->sreg1 + 1, 0); + MONO_EMIT_NEW_UNALU (cfg, OP_PPC_SUBFZE, ins->dreg + 2, ins->sreg1 + 2); NULLIFY_INS (ins); break; default: @@ -2903,12 +2906,12 @@ ppc_patch_full (guchar *code, const guchar *target, gboolean is_fd) /* the trampoline code will try to patch the blrl, blr, bcctr */ if (ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { branch_ins = seq; - if (ppc_opcode (seq [-3]) == 58 || ppc_opcode (seq [-3]) == 31) /* ld || mr */ + if (ppc_is_load_op (seq [-3]) || ppc_opcode (seq [-3]) == 31) /* ld || lwz || mr */ code -= 32; else code -= 24; } else { - if (ppc_opcode (seq [5]) == 58 || ppc_opcode (seq [5]) == 31) /* ld || mr */ + if (ppc_is_load_op (seq [5]) || ppc_opcode (seq [5]) == 31) /* ld || lwz || mr */ branch_ins = seq + 8; else branch_ins = seq + 6; @@ -2918,8 +2921,8 @@ ppc_patch_full (guchar *code, const guchar *target, gboolean is_fd) /* this is the lis/ori/sldi/oris/ori/(ld/ld|mr/nop)/mtlr/blrl sequence */ g_assert (mono_ppc_is_direct_call_sequence (branch_ins)); - if (ppc_opcode (seq [5]) == 58) { /* ld */ - g_assert (ppc_opcode (seq [6]) == 58); /* ld */ + if (ppc_is_load_op (seq [5])) { + g_assert (ppc_is_load_op (seq [6])); if (!is_fd) { guint8 *buf = (guint8*)&seq [5]; @@ -3007,7 +3010,7 @@ emit_load_volatile_arguments (MonoCompile *cfg, guint8 *code) pos = 0; - cinfo = calculate_sizes (sig, sig->pinvoke); + cinfo = calculate_sizes (cfg->generic_sharing_context, sig, sig->pinvoke); if (MONO_TYPE_ISSTRUCT (sig->ret)) { ArgInfo *ainfo = &cinfo->ret; @@ -3147,7 +3150,7 @@ ins_native_length (MonoCompile *cfg, MonoInst *ins) call = (MonoCallInst*)ins; sig = mono_method_signature (cfg->method); - cinfo = calculate_sizes (sig, sig->pinvoke); + cinfo = calculate_sizes (cfg->generic_sharing_context, sig, sig->pinvoke); if (MONO_TYPE_ISSTRUCT (sig->ret)) len += 4; @@ -3228,6 +3231,7 @@ emit_unreserve_param_area (MonoCompile *cfg, guint8 *code) #define MASK_SHIFT_IMM(i) ((i) & MONO_PPC_32_64_CASE (0x1f, 0x3f)) +#ifndef DISABLE_JIT void mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) { @@ -3547,7 +3551,22 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } break; case OP_BREAK: - ppc_break (code); + /* + * gdb does not like encountering a trap in the debugged code. So + * instead of emitting a trap, we emit a call a C function and place a + * breakpoint there. + */ + //ppc_break (code); + ppc_mr (code, ppc_r3, ins->sreg1); + mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, + (gpointer)"mono_break"); + if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { + ppc_load_func (code, ppc_r0, 0); + ppc_mtlr (code, ppc_r0); + ppc_blrl (code); + } else { + ppc_bl (code, 0); + } break; case OP_ADDCC: case OP_IADDCC: @@ -3702,7 +3721,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_sldi (code, ppc_r0, ppc_r0, 32); #endif ppc_compare (code, 0, ins->sreg1, ppc_r0); - EMIT_COND_SYSTEM_EXCEPTION_FLAGS (PPC_BR_TRUE, PPC_BR_EQ, "ArithmeticException"); + EMIT_COND_SYSTEM_EXCEPTION_FLAGS (PPC_BR_TRUE, PPC_BR_EQ, "OverflowException"); ppc_patch (divisor_is_m1, code); /* XER format: SO, OV, CA, reserved [21 bits], count [8 bits] */ @@ -4015,7 +4034,13 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_VCALL2_MEMBASE: case OP_VOIDCALL_MEMBASE: case OP_CALL_MEMBASE: - ppc_ldptr (code, ppc_r0, ins->inst_offset, ins->sreg1); + if (cfg->compile_aot && ins->sreg1 == ppc_r11) { + /* The trampolines clobber this */ + ppc_mr (code, ppc_r29, ins->sreg1); + ppc_ldptr (code, ppc_r0, ins->inst_offset, ppc_r29); + } else { + ppc_ldptr (code, ppc_r0, ins->inst_offset, ins->sreg1); + } ppc_mtlr (code, ppc_r0); ppc_blrl (code); /* FIXME: this should be handled somewhere else in the new jit */ @@ -4132,6 +4157,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_CALL_HANDLER: mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_target_bb); ppc_bl (code, 0); + mono_cfg_add_try_hole (cfg, ins->inst_eh_block, code, bb); break; case OP_LABEL: ins->inst_c0 = code - cfg->native_code; @@ -4454,7 +4480,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) EMIT_COND_SYSTEM_EXCEPTION (CEE_BEQ - CEE_BEQ, "ArithmeticException"); break; case OP_JUMP_TABLE: - mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0); + mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_c1, ins->inst_p0); #ifdef __mono_ppc64__ ppc_load_sequence (code, ins->dreg, (guint64)0x0f0f0f0f0f0f0f0fLL); #else @@ -4637,6 +4663,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) cfg->code_len = code - cfg->native_code; } +#endif /* !DISABLE_JIT */ void mono_arch_register_lowlevel_calls (void) @@ -4662,8 +4689,9 @@ mono_arch_register_lowlevel_calls (void) } while (0) #endif +#ifndef DISABLE_JIT 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; gboolean compile_aot = !run_cctors; @@ -4819,7 +4847,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) tracing = 1; sig = mono_method_signature (method); - cfg->code_size = MONO_PPC_32_64_CASE (260, 384) + sig->param_count * 20; + cfg->code_size = 512 + sig->param_count * 32; code = cfg->native_code = g_malloc (cfg->code_size); cfa_offset = 0; @@ -4903,7 +4931,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) /* load arguments allocated to register from the stack */ pos = 0; - cinfo = calculate_sizes (sig, sig->pinvoke); + cinfo = calculate_sizes (cfg->generic_sharing_context, sig, sig->pinvoke); if (MONO_TYPE_ISSTRUCT (sig->ret)) { ArgInfo *ainfo = &cinfo->ret; @@ -4949,7 +4977,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) } else { if (ppc_is_imm32 (inst->inst_offset)) { ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset)); - ppc_stb (code, ainfo->reg, ppc_r11, inst->inst_offset); + ppc_stb (code, ainfo->reg, inst->inst_offset, ppc_r11); } else { ppc_load (code, ppc_r11, inst->inst_offset); ppc_stbx (code, ainfo->reg, inst->inst_basereg, ppc_r11); @@ -4962,7 +4990,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) } else { if (ppc_is_imm32 (inst->inst_offset)) { ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset)); - ppc_sth (code, ainfo->reg, ppc_r11, inst->inst_offset); + ppc_sth (code, ainfo->reg, inst->inst_offset, ppc_r11); } else { ppc_load (code, ppc_r11, inst->inst_offset); ppc_sthx (code, ainfo->reg, inst->inst_basereg, ppc_r11); @@ -4976,7 +5004,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) } else { if (ppc_is_imm32 (inst->inst_offset)) { ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset)); - ppc_stw (code, ainfo->reg, ppc_r11, inst->inst_offset); + ppc_stw (code, ainfo->reg, inst->inst_offset, ppc_r11); } else { ppc_load (code, ppc_r11, inst->inst_offset); ppc_stwx (code, ainfo->reg, inst->inst_basereg, ppc_r11); @@ -5010,7 +5038,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) } else { if (ppc_is_imm32 (inst->inst_offset)) { ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset)); - ppc_stptr (code, ainfo->reg, ppc_r11, inst->inst_offset); + ppc_stptr (code, ainfo->reg, inst->inst_offset, ppc_r11); } else { ppc_load (code, ppc_r11, inst->inst_offset); ppc_stptr_indexed (code, ainfo->reg, inst->inst_basereg, ppc_r11); @@ -5030,7 +5058,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) } else { if (ppc_is_imm32 (inst->inst_offset)) { ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset)); - ppc_stb (code, ppc_r0, ppc_r11, inst->inst_offset); + ppc_stb (code, ppc_r0, inst->inst_offset, ppc_r11); } else { ppc_load (code, ppc_r11, inst->inst_offset); ppc_stbx (code, ppc_r0, inst->inst_basereg, ppc_r11); @@ -5043,7 +5071,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) } else { if (ppc_is_imm32 (inst->inst_offset)) { ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset)); - ppc_sth (code, ppc_r0, ppc_r11, inst->inst_offset); + ppc_sth (code, ppc_r0, inst->inst_offset, ppc_r11); } else { ppc_load (code, ppc_r11, inst->inst_offset); ppc_sthx (code, ppc_r0, inst->inst_basereg, ppc_r11); @@ -5057,7 +5085,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) } else { if (ppc_is_imm32 (inst->inst_offset)) { ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset)); - ppc_stw (code, ppc_r0, ppc_r11, inst->inst_offset); + ppc_stw (code, ppc_r0, inst->inst_offset, ppc_r11); } else { ppc_load (code, ppc_r11, inst->inst_offset); ppc_stwx (code, ppc_r0, inst->inst_basereg, ppc_r11); @@ -5095,7 +5123,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) } else { if (ppc_is_imm32 (inst->inst_offset)) { ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset)); - ppc_stptr (code, ppc_r0, ppc_r11, inst->inst_offset); + ppc_stptr (code, ppc_r0, inst->inst_offset, ppc_r11); } else { ppc_load (code, ppc_r11, inst->inst_offset); ppc_stptr_indexed (code, ppc_r0, inst->inst_basereg, ppc_r11); @@ -5397,6 +5425,7 @@ mono_arch_emit_epilog (MonoCompile *cfg) g_assert (cfg->code_len < cfg->code_size); } +#endif /* ifndef DISABLE_JIT */ /* remove once throw_exception_by_name is eliminated */ static int @@ -5416,20 +5445,28 @@ exception_id_by_name (const char *name) return MONO_EXC_NULL_REF; if (strcmp (name, "ArrayTypeMismatchException") == 0) return MONO_EXC_ARRAY_TYPE_MISMATCH; + if (strcmp (name, "ArgumentException") == 0) + return MONO_EXC_ARGUMENT; g_error ("Unknown intrinsic exception %s\n", name); return 0; } +#ifndef DISABLE_JIT void mono_arch_emit_exceptions (MonoCompile *cfg) { MonoJumpInfo *patch_info; int i; guint8 *code; - const guint8* exc_throw_pos [MONO_EXC_INTRINS_NUM] = {NULL}; - guint8 exc_throw_found [MONO_EXC_INTRINS_NUM] = {0}; + guint8* exc_throw_pos [MONO_EXC_INTRINS_NUM]; + guint8 exc_throw_found [MONO_EXC_INTRINS_NUM]; int max_epilog_size = 50; + for (i = 0; i < MONO_EXC_INTRINS_NUM; i++) { + exc_throw_pos [i] = NULL; + exc_throw_found [i] = 0; + } + /* count the number of exception infos */ /* @@ -5507,7 +5544,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg) unsigned char *ip = patch_info->ip.i + cfg->native_code; i = exception_id_by_name (patch_info->data.target); - if (exc_throw_pos [i]) { + if (exc_throw_pos [i] && !(ip > exc_throw_pos [i] && ip - exc_throw_pos [i] > 50000)) { ppc_patch (ip, exc_throw_pos [i]); patch_info->type = MONO_PATCH_INFO_NONE; break; @@ -5545,6 +5582,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg) g_assert (cfg->code_len <= cfg->code_size); } +#endif #if DEAD_CODE static int @@ -5766,26 +5804,26 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI } size += item->chunk_size; } + /* the initial load of the vtable address */ + size += PPC_LOAD_SEQUENCE_LENGTH + LOADSTORE_SIZE; if (fail_tramp) { code = mono_method_alloc_generic_virtual_thunk (domain, size); } else { - /* the initial load of the vtable address */ - size += PPC_LOAD_SEQUENCE_LENGTH + LOADSTORE_SIZE; code = mono_domain_code_reserve (domain, size); } start = code; - if (!fail_tramp) { - /* - * We need to save and restore r11 because it might be - * used by the caller as the vtable register, so - * clobbering it will trip up the magic trampoline. - * - * FIXME: Get rid of this by making sure that r11 is - * not used as the vtable register in interface calls. - */ - ppc_stptr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_sp); - ppc_load (code, ppc_r11, (gsize)(& (vtable->vtable [0]))); - } + + /* + * We need to save and restore r11 because it might be + * used by the caller as the vtable register, so + * clobbering it will trip up the magic trampoline. + * + * FIXME: Get rid of this by making sure that r11 is + * not used as the vtable register in interface calls. + */ + ppc_stptr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_sp); + ppc_load (code, ppc_r11, (gsize)(& (vtable->vtable [0]))); + for (i = 0; i < count; ++i) { MonoIMTCheckItem *item = imt_entries [i]; item->code_target = code; @@ -5885,6 +5923,16 @@ mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code) return (MonoVTable*)(gsize) r [MONO_ARCH_RGCTX_REG]; } +GSList* +mono_arch_get_cie_program (void) +{ + GSList *l = NULL; + + mono_add_unwind_op_def_cfa (l, (guint8*)NULL, (guint8*)NULL, ppc_r1, 0); + + return l; +} + MonoInst* mono_arch_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) {