* exceptions-mips.c: fix mono_arch_ip_from_context(), increase
authorMark Mason <glowingpurple@gmail.com>
Fri, 19 Jan 2007 21:46:21 +0000 (21:46 -0000)
committerMark Mason <glowingpurple@gmail.com>
Fri, 19 Jan 2007 21:46:21 +0000 (21:46 -0000)
exception debug support.
* mini-mips.c: more configuration macros, support long
conditional branches, additional
asserts, fix epilog instrumentation.
* mini-mips.h: use standard stack walk
* cpu-mips.md: increase size of div, rem and conditional branches

These changes submitted under the MIT/X11 license.

svn path=/trunk/mono/; revision=71368

mono/mini/ChangeLog
mono/mini/cpu-mips.md
mono/mini/exceptions-mips.c
mono/mini/mini-mips.c
mono/mini/mini-mips.h

index f1f1da286e13e9bc5bd0abd5430a060c5757910c..b0aa2cbc0fd2283d210a2c2167e94f82f6526877 100644 (file)
@@ -1,4 +1,11 @@
+2007-01-19 Mark Mason <mason@broadcom.com>
 
+       * exceptions-mips.c: fix mono_arch_ip_from_context(), increase exception debug support.
+       * mini-mips.c: more configuration macros, support long conditional branches, additional
+       asserts, fix epilog instrumentation.
+       * mini-mips.h: use standard stack walk
+       * cpu-mips.md: increase size of div, rem and conditional branches
+       
 Fri Jan 19 17:23:32 CET 2007 Paolo Molaro <lupus@ximian.com>
 
        * mini.h, mini-codegen.c, mini-$(arch).h: claenup references
index cd2713bd21bf0b37cb3777930add73d2a6bc4679..0936e4dc392bed4c5bc6ff433d818ede2e6a62c6 100644 (file)
@@ -107,7 +107,7 @@ bge.un.s: len:8
 bgt.un.s: len:8
 ble.un.s: len:8
 blt.un.s: len:8
-br: len:8
+br: len:16
 brfalse: len:8
 brtrue: len:8
 beq: len:8
@@ -142,10 +142,10 @@ stind.r8: src1:b src2:f
 add: dest:i src1:i src2:i len:4
 sub: dest:i src1:i src2:i len:4
 mul: dest:i src1:i src2:i len:20
-div: dest:i src1:i src2:i len:72
-div.un: dest:i src1:i src2:i len:72
-rem: dest:i src1:i src2:i len:72
-rem.un: dest:i src1:i src2:i len:72
+div: dest:i src1:i src2:i len:76
+div.un: dest:i src1:i src2:i len:76
+rem: dest:i src1:i src2:i len:76
+rem.un: dest:i src1:i src2:i len:76
 and: dest:i src1:i src2:i len:4
 or: dest:i src1:i src2:i len:4
 xor: dest:i src1:i src2:i len:4
@@ -540,12 +540,12 @@ br_reg: src1:i len:8
 op_bigmul: len:52 dest:l src1:i src2:i
 op_bigmul_un: len:52 dest:l src1:i src2:i
 tls_get: len:8 dest:i
-mips_beq: src1:i src2:i len:8
-mips_bgez: src1:i len:8
-mips_bgtz: src1:i len:8
-mips_blez: src1:i len:8
-mips_bltz: src1:i len:8
-mips_bne: src1:i src2:i len:8
+mips_beq: src1:i src2:i len:24
+mips_bgez: src1:i len:24
+mips_bgtz: src1:i len:24
+mips_blez: src1:i len:24
+mips_bltz: src1:i len:24
+mips_bne: src1:i src2:i len:24
 mips_cvtsd: dest:f src1:f len:8
 mips_fbeq: src1:f src2:f len:16
 mips_fbge: src1:f src2:f len:16
index 5d4ce065b97e46590108e59a1e400d42cf2ce482..fa8eb8d8bf776657668be574ec4f3a73fb84acac 100644 (file)
@@ -193,8 +193,8 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean
        static void (*restore_context) (MonoContext *);
        MonoContext ctx;
 
-#if 0
-       printf("throw_exception: exc=%p eip=%x esp=%x rethrow=%d\n",
+#ifdef DEBUG_EXCEPTIONS
+       g_print ("throw_exception: exc=%p eip=%x esp=%x rethrow=%d\n",
               exc, (unsigned int) eip, (unsigned int) esp, rethrow);
 #endif
 
@@ -206,7 +206,7 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean
 
        setup_context (&ctx);
 
-       /*printf ("stack in throw: %p\n", esp);*/
+       /*g_print  ("stack in throw: %p\n", esp);*/
        memcpy (&ctx.sc_regs, (void *)(esp + MIPS_STACK_PARAM_OFFSET),
                sizeof (gulong) * MONO_SAVED_GREGS);
 #if 0
@@ -225,6 +225,9 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean
        arch_handle_exception (&ctx, exc, FALSE);
 #else
        mono_handle_exception (&ctx, exc, (void *)eip, FALSE);
+#endif
+#ifdef DEBUG_EXCEPTIONS
+       g_print ("throw_exception: restore to %p\n", (void *) ctx.sc_pc);
 #endif
        restore_context (&ctx);
 
@@ -248,7 +251,7 @@ mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_name, gbo
 
        code = start;
 
-       //printf("mono_arch_get_throw_exception_generic: code=%p\n", code);
+       //g_print ("mono_arch_get_throw_exception_generic: code=%p\n", code);
 
        pos = 0;
        /* XXX - save all the FP regs on the stack ? */
@@ -669,8 +672,8 @@ mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
 gpointer
 mono_arch_ip_from_context (void *sigctx)
 {
-       struct ucontext *uc = sigctx;
-       return (gpointer)(guint32)uc->uc_mcontext.pc;
+       struct sigcontext *ctx = (struct sigcontext *)sigctx;
+       return (gpointer)(guint32)ctx->sc_pc;
 }
 
 /*
@@ -683,6 +686,9 @@ mono_arch_handle_exception (void *ctx, gpointer obj, gboolean test_only)
        gboolean result;
        
        mono_arch_sigctx_to_monoctx (ctx, &mctx);
+#ifdef DEBUG_EXCEPTIONS
+       g_print ("mono_arch_handle_exception: pc=%p\n", mctx.sc_pc);
+#endif
 #ifdef CUSTOM_EXCEPTION_HANDLING
        result = arch_handle_exception (&mctx, obj, test_only);
 #else
@@ -690,6 +696,9 @@ mono_arch_handle_exception (void *ctx, gpointer obj, gboolean test_only)
        result = TRUE;
 #endif
 
+#ifdef DEBUG_EXCEPTIONS
+       g_print ("mono_arch_handle_exception: restore pc=%p\n", mctx.sc_pc);
+#endif
        /* restore the context so that returning from the signal handler
         * will invoke the catch clause 
         */
@@ -824,7 +833,7 @@ arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
                                                        }
                                                        if (mono_jit_trace_calls != NULL)
                                                                g_print ("EXCEPTION: catch found at clause %d of %s\n", i, mono_method_full_name (ji->method, TRUE));
-                                                       /*printf ("stack for catch: %p\n", MONO_CONTEXT_GET_BP (ctx));*/
+                                                       /*g_print  ("stack for catch: %p\n", MONO_CONTEXT_GET_BP (ctx));*/
                                                        MONO_CONTEXT_SET_IP (ctx, ei->handler_start);
                                                        jit_tls->lmf = lmf;
                                                        return 0;
index 02a6e802c4d577ef7fb18818fe20c8af1cb18f82..892d86548428c4be357cec84c6b84bc68ba70483 100644 (file)
 #include "cpu-mips.h"
 #include "trace.h"
 
-#undef SAVE_FP_REGS
-#define SAVE_LMF
-#define ALWAYS_USE_FP  1
-#define ALWAYS_SAVE_RA 1       /* call-handler & switch currently clobber ra */
+#define SAVE_FP_REGS           0
+#define SAVE_ALL_REGS          1
+#define EXTRA_STACK_SPACE      0       /* suppresses some s-reg corruption issues */
+#define LONG_BRANCH            0
+
+#define SAVE_LMF               1
+#define ALWAYS_USE_FP          1
+#define ALWAYS_SAVE_RA         1       /* call-handler & switch currently clobber ra */
 
 enum {
        TLS_MODE_DETECT,
@@ -154,6 +158,109 @@ mips_emit_exc_by_name(guint8 *code, char *name)
        return code;
 }
 
+static guint8 *
+mips_emit_cond_branch (MonoCompile *cfg, guint8 *code, int op, MonoInst *ins)
+{
+       int br_offset = 5;
+
+       g_assert (ins);
+#if LONG_BRANCH
+       /* Invert test and emit branch around jump */
+       switch (op) {
+       case OP_MIPS_BEQ:
+               op = OP_MIPS_BNE;
+               break;
+       case OP_MIPS_BNE:
+               op = OP_MIPS_BEQ;
+               break;
+       case OP_MIPS_BGEZ:
+               op = OP_MIPS_BLTZ;
+               break;
+       case OP_MIPS_BGTZ:
+               op = OP_MIPS_BLEZ;
+               break;
+       case OP_MIPS_BLEZ:
+               op = OP_MIPS_BGTZ;
+               break;
+       case OP_MIPS_BLTZ:
+               op = OP_MIPS_BGEZ;
+               break;
+       default:
+               g_assert_not_reached ();
+       }
+       switch (op) {
+       case OP_MIPS_BEQ:
+               mips_beq (code, ins->sreg1, ins->sreg2, br_offset);
+               mips_nop (code);
+               break;
+       case OP_MIPS_BNE:
+               mips_bne (code, ins->sreg1, ins->sreg2, br_offset);
+               mips_nop (code);
+               break;
+       case OP_MIPS_BGEZ:
+               mips_bgez (code, ins->sreg1, br_offset);
+               mips_nop (code);
+               break;
+       case OP_MIPS_BGTZ:
+               mips_bgtz (code, ins->sreg1, br_offset);
+               mips_nop (code);
+               break;
+       case OP_MIPS_BLEZ:
+               mips_blez (code, ins->sreg1, br_offset);
+               mips_nop (code);
+               break;
+       case OP_MIPS_BLTZ:
+               mips_bltz (code, ins->sreg1, br_offset);
+               mips_nop (code);
+               break;
+       }
+       if (ins->flags & MONO_INST_BRLABEL)
+               mono_add_patch_info (cfg, code - cfg->native_code,
+                                    MONO_PATCH_INFO_LABEL, ins->inst_i0);
+       else
+               mono_add_patch_info (cfg, code - cfg->native_code,
+                                    MONO_PATCH_INFO_BB, ins->inst_true_bb);
+       mips_lui (code, mips_at, mips_zero, 0);
+       mips_addiu (code, mips_at, mips_at, 0);
+       mips_jr (code, mips_at);
+       mips_nop (code);
+#else
+       if (ins->flags & MONO_INST_BRLABEL)
+               mono_add_patch_info (cfg, code - cfg->native_code,
+                                    MONO_PATCH_INFO_LABEL, ins->inst_i0);
+       else
+               mono_add_patch_info (cfg, code - cfg->native_code,
+                                    MONO_PATCH_INFO_BB, ins->inst_true_bb);
+       switch (op) {
+       case OP_MIPS_BEQ:
+               mips_beq (code, ins->sreg1, ins->sreg2, 0);
+               mips_nop (code);
+               break;
+       case OP_MIPS_BNE:
+               mips_bne (code, ins->sreg1, ins->sreg2, 0);
+               mips_nop (code);
+               break;
+       case OP_MIPS_BGEZ:
+               mips_bgez (code, ins->sreg1, 0);
+               mips_nop (code);
+               break;
+       case OP_MIPS_BGTZ:
+               mips_bgtz (code, ins->sreg1, 0);
+               mips_nop (code);
+               break;
+       case OP_MIPS_BLEZ:
+               mips_blez (code, ins->sreg1, 0);
+               mips_nop (code);
+               break;
+       case OP_MIPS_BLTZ:
+               mips_bltz (code, ins->sreg1, 0);
+               mips_nop (code);
+               break;
+       }
+#endif
+       return (code);
+}
+
 /* XXX - big-endian dependent? */
 void
 patch_lui_addiu(guint32 *ip, guint32 val)
@@ -173,6 +280,7 @@ patch_lui_addiu(guint32 *ip, guint32 val)
        mono_arch_flush_icache ((guint8 *)ip, 8);
 }
 
+guint32 trap_target;
 void
 mips_patch (guint32 *code, guint32 target)
 {
@@ -180,6 +288,7 @@ mips_patch (guint32 *code, guint32 target)
        guint32 op = ins >> 26;
        guint32 diff, offset;
 
+       g_assert (trap_target != target);
        //printf ("patching 0x%08x (0x%08x) to point to 0x%08x\n", code, ins, target);
        switch (op) {
        case 0x00: /* jr ra */
@@ -189,6 +298,8 @@ mips_patch (guint32 *code, guint32 target)
                break;
        case 0x02: /* j */
        case 0x03: /* jal */
+               g_assert (!(target & 0x03));
+               g_assert ((target & 0xfc000000) == (((guint32)code) & 0xfc000000));
                ins = (ins & 0xfc000000) | (((target) >> 2) & 0x03ffffff);
                *code = ins;
                mono_arch_flush_icache ((guint8 *)code, 4);
@@ -200,7 +311,10 @@ mips_patch (guint32 *code, guint32 target)
        case 0x07: /* BGTZ */
        case 0x11: /* bc1t */
                diff = target - (guint32)(code + 1);
-               offset = diff >> 2;
+               g_assert (((diff & 0x0003ffff) == diff) || ((diff | 0xfffc0000) == diff));
+               g_assert (!(diff & 0x03));
+               offset = ((gint32)diff) >> 2;
+               g_assert (((int)offset) == ((int)(short)offset));
                ins = (ins & 0xffff0000) | (offset & 0x0000ffff);
                *code = ins;
                mono_arch_flush_icache ((guint8 *)code, 4);
@@ -931,7 +1045,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        }
 
        /* Space for LMF (if needed) */
-#ifdef SAVE_LMF
+#if SAVE_LMF
        if (cfg->method->save_lmf) {
                /* align the offset to 16 bytes */
                offset = (offset + MIPS_STACK_ALIGNMENT - 1) & ~(MIPS_STACK_ALIGNMENT - 1);
@@ -948,7 +1062,11 @@ mono_arch_allocate_vars (MonoCompile *cfg)
 #endif
        /* Space for saved registers */
        cfg->arch.iregs_offset = offset;
+#if SAVE_ALL_REGS
+       iregs_to_save = MONO_ARCH_CALLEE_SAVED_REGS;
+#else
        iregs_to_save = (cfg->used_int_regs & MONO_ARCH_CALLEE_SAVED_REGS);
+#endif
        if (iregs_to_save) {
                for (i = MONO_MAX_IREGS-1; i >= 0; --i) {
                        if (iregs_to_save & (1 << i)) {
@@ -965,7 +1083,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
 #endif
 
        /* saved float registers */
-#ifdef SAVE_FP_REGS
+#if SAVE_FP_REGS
        fregs_to_restore = (cfg->used_float_regs & MONO_ARCH_CALLEE_SAVED_FREGS);
        if (fregs_to_restore) {
                for (i = MONO_MAX_FREGS-1; i >= 0; --i) {
@@ -2071,15 +2189,16 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
                        mips_patch (divisor_is_m1, (guint32)code);
 
-                       /* Put divide in branch delay slot */
+                       /* Put divide in branch delay slot (NOT YET) */
                        divisor_is_zero = (guint32 *)code;
                        mips_bne (code, ins->sreg2, mips_zero, 0);
-                       mips_div (code, ins->sreg1, ins->sreg2);
+                       mips_nop (code);
 
                        /* Divide by zero -- throw exception */
                        EMIT_SYSTEM_EXCEPTION_NAME("DivideByZeroException");
 
                        mips_patch (divisor_is_zero, (guint32)code);
+                       mips_div (code, ins->sreg1, ins->sreg2);
                        if (ins->opcode == CEE_DIV)
                                mips_mflo (code, ins->dreg);
                        else
@@ -2089,14 +2208,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case CEE_DIV_UN: {
                        guint32 *divisor_is_zero = (guint32 *)(void *)code;
 
-                       /* Put divide in branch delay slot */
+                       /* Put divide in branch delay slot (NOT YET) */
                        mips_bne (code, ins->sreg2, mips_zero, 0);
-                       mips_divu (code, ins->sreg1, ins->sreg2);
+                       mips_nop (code);
 
                        /* Divide by zero -- throw exception */
                        EMIT_SYSTEM_EXCEPTION_NAME("DivideByZeroException");
 
                        mips_patch (divisor_is_zero, (guint32)code);
+                       mips_divu (code, ins->sreg1, ins->sreg2);
                        mips_mflo (code, ins->dreg);
                        break;
                }
@@ -2115,14 +2235,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case CEE_REM_UN: {
                        guint32 *divisor_is_zero = (guint32 *)(void *)code;
 
-                       /* Put divide in branch delay slot */
+                       /* Put divide in branch delay slot (NOT YET) */
                        mips_bne (code, ins->sreg2, mips_zero, 0);
-                       mips_divu (code, ins->sreg1, ins->sreg2);
+                       mips_nop (code);
 
                        /* Divide by zero -- throw exception */
                        EMIT_SYSTEM_EXCEPTION_NAME("DivideByZeroException");
 
                        mips_patch (divisor_is_zero, (guint32)code);
+                       mips_divu (code, ins->sreg1, ins->sreg2);
                        mips_mfhi (code, ins->dreg);
                        break;
                }
@@ -2336,8 +2457,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
 #endif
                        mono_add_patch_info (cfg, (guint8*) code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, ins->inst_p0);
+#if LONG_BRANCH
+                       mips_lui (code, mips_at, mips_zero, 0);
+                       mips_addiu (code, mips_at, mips_at, 0);
+                       mips_jr (code, mips_at);
+                       mips_nop (code);
+#else
                        mips_beq (code, mips_zero, mips_zero, 0);
                        mips_nop (code);
+#endif
                        break;
                }
                case OP_CHECK_THIS:
@@ -2504,13 +2632,18 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case CEE_BR:
                        if (ins->flags & MONO_INST_BRLABEL) {
                                mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_LABEL, ins->inst_i0);
-                               mips_beq (code, mips_zero, mips_zero, 0);
-                               mips_nop (code);
                        } else {
                                mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_target_bb);
-                               mips_beq (code, mips_zero, mips_zero, 0);
-                               mips_nop (code);
                        }
+#if 0
+                       mips_beq (code, mips_zero, mips_zero, 0);
+                       mips_nop (code);
+#else
+                       mips_lui (code, mips_at, mips_zero, 0);
+                       mips_addiu (code, mips_at, mips_at, 0);
+                       mips_jr (code, mips_at);
+                       mips_nop (code);
+#endif
                        break;
                case OP_BR_REG:
                        mips_jr (code, ins->sreg1);
@@ -2687,52 +2820,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        g_assert_not_reached ();
                        break;
                case OP_MIPS_BEQ:
-                       if (ins->flags & MONO_INST_BRLABEL)
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_LABEL, ins->inst_i0);
-                       else
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_true_bb);
-                       mips_beq (code, ins->sreg1, ins->sreg2, 0);
-                       mips_nop (code);
-                       break;
                case OP_MIPS_BNE:
-                       if (ins->flags & MONO_INST_BRLABEL)
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_LABEL, ins->inst_i0);
-                       else
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_true_bb);
-                       mips_bne (code, ins->sreg1, ins->sreg2, 0);
-                       mips_nop (code);
-                       break;
                case OP_MIPS_BGEZ:
-                       if (ins->flags & MONO_INST_BRLABEL)
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_LABEL, ins->inst_i0);
-                       else
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_true_bb);
-                       mips_bgez (code, ins->sreg1, 0);
-                       mips_nop (code);
-                       break;
                case OP_MIPS_BGTZ:
-                       if (ins->flags & MONO_INST_BRLABEL)
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_LABEL, ins->inst_i0);
-                       else
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_true_bb);
-                       mips_bgtz (code, ins->sreg1, 0);
-                       mips_nop (code);
-                       break;
                case OP_MIPS_BLEZ:
-                       if (ins->flags & MONO_INST_BRLABEL)
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_LABEL, ins->inst_i0);
-                       else
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_true_bb);
-                       mips_blez (code, ins->sreg1, 0);
-                       mips_nop (code);
-                       break;
                case OP_MIPS_BLTZ:
-                       if (ins->flags & MONO_INST_BRLABEL)
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_LABEL, ins->inst_i0);
-                       else
-                               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_BB, ins->inst_true_bb);
-                       mips_bltz (code, ins->sreg1, 0);
-                       mips_nop (code);
+                       code = mips_emit_cond_branch (cfg, code, ins->opcode, ins);
                        break;
 
                /* floating point opcodes */
@@ -3254,8 +3347,12 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        alloc_size = cfg->stack_offset;
        cfg->stack_usage = alloc_size;
 
+#if SAVE_ALL_REGS
+       iregs_to_save = MONO_ARCH_CALLEE_SAVED_REGS;
+#else
        iregs_to_save = (cfg->used_int_regs & MONO_ARCH_CALLEE_SAVED_REGS);
-#ifdef SAVE_FP_REGS
+#endif
+#if SAVE_FP_REGS
 #if 0
        fregs_to_save = (cfg->used_float_regs & MONO_ARCH_CALLEE_SAVED_FREGS);
 #else
@@ -3296,7 +3393,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                }
        }
 
-#ifdef SAVE_FP_REGS
+#if SAVE_FP_REGS
        /* Save float registers */
        if (fregs_to_save) {
                for (i = MONO_MAX_FREGS-1; i >= 0; --i) {
@@ -3307,8 +3404,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                        }
                }
        }
-#endif
-#ifdef SAVE_LMF
+#if SAVE_LMF
        if (method->save_lmf) {
 #if 0
                ppc_stmw (code, ppc_r13, ppc_r1, ofs);
@@ -3317,6 +3413,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                }
 #endif
        }
+#endif
 #endif
        if (cfg->frame_reg != mips_sp)
                mips_move (code, cfg->frame_reg, mips_sp);
@@ -3446,15 +3543,20 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        }
 
        if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
-               g_assert_not_reached();
+               mips_load_const (code, mips_a0, cfg->domain);
 #if 0
-               ppc_load (code, ppc_r3, cfg->domain);
-               mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_jit_thread_attach");
-               ppc_bl (code, 0);
+               mono_add_patch_info (cfg, code - cfg->native_code,
+                                    MONO_PATCH_INFO_INTERNAL_METHOD,
+                                    (gpointer)"mono_jit_thread_attach");
+               mips_lui (code, mips_t9, mips_zero, 0);
+               mips_addiu (code, mips_t9, mips_t9, 0);
 #endif
+               mips_load_const (code, mips_t9, (gpointer)mono_jit_thread_attach);
+               mips_jalr (code, mips_t9, mips_ra);
+               mips_nop (code);
        }
 
-#ifdef SAVE_LMF
+#if SAVE_LMF
        if (method->save_lmf) {
                if (lmf_pthread_key != -1) {
                        g_assert_not_reached();
@@ -3464,6 +3566,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                        if (G_STRUCT_OFFSET (MonoJitTlsData, lmf))
                                mips_addiu (code, mips_a0, mips_temp, G_STRUCT_OFFSET (MonoJitTlsData, lmf));
                } else {
+                       /* This can/will clobber the a0-a3 registers */
                        mips_load_const (code, mips_t9, (gpointer)mono_get_lmf_addr);
                        mips_jalr (code, mips_t9, mips_ra);
                        mips_nop (code);
@@ -3533,7 +3636,7 @@ mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean ena
        int offset;
        MonoMethod *method = cfg->method;
        int rtype = mono_type_get_underlying_type (mono_method_signature (method)->ret)->type;
-       int save_offset = MIPS_STACK_PARAM_OFFSET + cfg->param_area;
+       int save_offset = 16;
 
        save_offset += 15;
        save_offset &= ~15;
@@ -3547,7 +3650,6 @@ mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean ena
        }
        mips_nop (code);
        mips_nop (code);
-       mips_nop (code);
        switch (rtype) {
        case MONO_TYPE_VOID:
                /* special case string .ctor icall */
@@ -3572,33 +3674,33 @@ mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean ena
                break;
        }
 
+       mips_addiu (code, mips_sp, mips_sp, -32);
        switch (save_mode) {
        case SAVE_TWO:
-               mips_sw (code, mips_v0, cfg->frame_reg, save_offset);
-               mips_sw (code, mips_v1, cfg->frame_reg, save_offset + 4);
+               mips_sw (code, mips_v0, mips_sp, save_offset);
+               mips_sw (code, mips_v1, mips_sp, save_offset + 4);
                if (enable_arguments) {
                        mips_move (code, mips_a1, mips_v0);
                        mips_move (code, mips_a2, mips_v1);
                }
                break;
        case SAVE_ONE:
-               mips_sw (code, mips_v0, cfg->frame_reg, save_offset);
+               mips_sw (code, mips_v0, mips_sp, save_offset);
                if (enable_arguments) {
                        mips_move (code, mips_a1, mips_v0);
                }
                break;
        case SAVE_FP:
-               mips_sdc1 (code, mips_f0, cfg->frame_reg, save_offset);
-               mips_ldc1 (code, mips_f12, cfg->frame_reg, save_offset);
-               mips_lw (code, mips_a0, cfg->frame_reg, save_offset);
-               mips_lw (code, mips_a1, cfg->frame_reg, save_offset+4);
+               mips_sdc1 (code, mips_f0, mips_sp, save_offset);
+               mips_ldc1 (code, mips_f12, mips_sp, save_offset);
+               mips_lw (code, mips_a0, mips_sp, save_offset);
+               mips_lw (code, mips_a1, mips_sp, save_offset+4);
                break;
        case SAVE_STRUCT:
        case SAVE_NONE:
        default:
                break;
        }
-
        mips_load_const (code, mips_a0, cfg->method);
        mips_load_const (code, mips_t9, func);
        mips_jalr (code, mips_t9, mips_ra);
@@ -3606,21 +3708,21 @@ mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean ena
 
        switch (save_mode) {
        case SAVE_TWO:
-               mips_lw (code, mips_v0, cfg->frame_reg, save_offset);
-               mips_lw (code, mips_v1, cfg->frame_reg, save_offset + 4);
+               mips_lw (code, mips_v0, mips_sp, save_offset);
+               mips_lw (code, mips_v1, mips_sp, save_offset + 4);
                break;
        case SAVE_ONE:
-               mips_lw (code, mips_v0, cfg->frame_reg, save_offset);
+               mips_lw (code, mips_v0, mips_sp, save_offset);
                break;
        case SAVE_FP:
-               mips_ldc1 (code, mips_f0, cfg->frame_reg, save_offset);
+               mips_ldc1 (code, mips_f0, mips_sp, save_offset);
                break;
        case SAVE_STRUCT:
        case SAVE_NONE:
        default:
                break;
        }
-       mips_nop (code);
+       mips_addiu (code, mips_sp, mips_sp, 32);
        mips_nop (code);
        mips_nop (code);
        return code;
@@ -3636,7 +3738,7 @@ mono_arch_emit_epilog (MonoCompile *cfg)
        guint32 iregs_to_restore;
        guint32 fregs_to_restore;
 
-#ifdef SAVE_LMF
+#if SAVE_LMF
        if (cfg->method->save_lmf)
                max_epilog_size += 128;
 #endif
@@ -3662,7 +3764,11 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                code = mono_arch_instrument_epilog (cfg, mono_trace_leave_method, code, TRUE);
        }
        pos = cfg->arch.iregs_offset;
+#if SAVE_ALL_REGS
+       iregs_to_restore = MONO_ARCH_CALLEE_SAVED_REGS;
+#else
        iregs_to_restore = (cfg->used_int_regs & MONO_ARCH_CALLEE_SAVED_REGS);
+#endif
        if (iregs_to_restore) {
                for (i = MONO_MAX_IREGS-1; i >= 0; --i) {
                        if (iregs_to_restore & (1 << i)) {
@@ -3672,7 +3778,7 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                }
        }
 
-#ifdef SAVE_FP_REGS
+#if SAVE_FP_REGS
 #if 0
        fregs_to_restore = (cfg->used_float_regs & MONO_ARCH_CALLEE_SAVED_FREGS);
 #else
@@ -3689,7 +3795,7 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                }
        }
 #endif
-#ifdef SAVE_LMF
+#if SAVE_LMF
        /* Unlink the LMF if necessary */
        if (method->save_lmf) {
                int lmf_offset = cfg->arch.lmf_offset;
index e79ee24a2d5fa6e4de537ab5cdcea7f4309edb84..9006ca78b267c1e9b53c97c409a481106c808d92 100644 (file)
@@ -227,7 +227,7 @@ typedef struct {
                MONO_CONTEXT_SET_IP ((ctx),ra); \
        } while (0)
 
-#if 1
+#if 0
 #define mono_find_jit_info mono_arch_find_jit_info
 #define CUSTOM_STACK_WALK
 #endif
@@ -235,6 +235,7 @@ typedef struct {
 /* re-attaches with gdb - sometimes causes executable to hang */
 #undef HAVE_BACKTRACE_SYMBOLS
 
+#undef DEBUG_EXCEPTIONS
 #undef CUSTOM_EXCEPTION_HANDLING
 
 #define MONO_ZERO_REG          mips_zero