2009-01-12 Mark Probst <mark.probst@gmail.com>
authorMark Probst <mark.probst@gmail.com>
Mon, 12 Jan 2009 15:35:06 +0000 (15:35 -0000)
committerMark Probst <mark.probst@gmail.com>
Mon, 12 Jan 2009 15:35:06 +0000 (15:35 -0000)
* mini-ppc.c, exceptions-ppc.c, cpu-ppc.md, cpu-ppc64.md: Don't
use the red zone.  Make room on the stack first and then use it,
not the other way around.

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

mono/mini/ChangeLog
mono/mini/cpu-ppc.md
mono/mini/cpu-ppc64.md
mono/mini/exceptions-ppc.c
mono/mini/mini-ppc.c

index b8d3e75ffec0400834988f5018031f9bef7db18b..747f13e8eb50071204aede580100d5cdba07bd08 100644 (file)
@@ -1,3 +1,9 @@
+2009-01-12  Mark Probst  <mark.probst@gmail.com>
+
+       * mini-ppc.c, exceptions-ppc.c, cpu-ppc.md, cpu-ppc64.md: Don't
+       use the red zone.  Make room on the stack first and then use it,
+       not the other way around.
+
 2009-01-12  Zoltan Varga  <vargaz@gmail.com>
 
        * mini.c (mini_init): Call mono_xdebug_init ().
index 2ea953b5516a1e8d88183d3a403ff219eb33464a..09381db6fb8cbce67c49aaac5d24a1f1eb110907 100644 (file)
@@ -49,7 +49,7 @@ memory_barrier: len:4
 nop: len:4
 relaxed_nop: len:4
 break: len:4
-jmp: len:104
+jmp: len:108
 call: dest:a clob:c len:16
 br: len:4
 throw: src1:i len:20
index 45289931322aa50f8a4f0e842c76c73fa27d1549..4ed9a1922cb0122df3f0ae165d063fbba0201c27 100644 (file)
@@ -49,7 +49,7 @@ memory_barrier: len:4
 nop: len:4
 relaxed_nop: len:4
 break: len:4
-jmp: len:92
+jmp: len:96
 call: dest:a clob:c len:36
 br: len:4
 throw: src1:i len:40
index 8a51642983bea1500ec338848abbd8bbc8941a27..66819cd2549cc416851930fc386feff3c17dcecf 100644 (file)
@@ -221,6 +221,27 @@ mono_arch_get_restore_context (void)
        return start;
 }
 
+#define SAVED_REGS_LENGTH              (sizeof (gdouble) * MONO_SAVED_FREGS + sizeof (gpointer) * MONO_SAVED_GREGS)
+#define ALIGN_STACK_FRAME_SIZE(s)      (((s) + MONO_ARCH_FRAME_ALIGNMENT - 1) & ~(MONO_ARCH_FRAME_ALIGNMENT - 1))
+/* The 64 bytes here are for outgoing arguments and a bit of spare.
+   We don't use it all, but it doesn't hurt. */
+#define REG_SAVE_STACK_FRAME_SIZE      (ALIGN_STACK_FRAME_SIZE (SAVED_REGS_LENGTH + PPC_MINIMAL_STACK_SIZE + 64))
+
+static guint8*
+emit_save_saved_regs (guint8 *code, int pos)
+{
+       int i;
+
+       for (i = 31; i >= 14; --i) {
+               pos -= sizeof (gdouble);
+               ppc_stfd (code, i, pos, ppc_sp);
+       }
+       pos -= sizeof (gpointer) * MONO_SAVED_GREGS;
+       ppc_store_multiple_regs (code, ppc_r13, ppc_sp, pos);
+
+       return code;
+}
+
 /*
  * mono_arch_get_call_filter:
  *
@@ -244,22 +265,11 @@ mono_arch_get_call_filter (void)
        code = start = mono_global_codeman_reserve (size);
        code = mono_ppc_create_pre_code_ftnptr (code);
 
-       /* save all the regs on the stack */
-       pos = 0;
-       for (i = 31; i >= 14; --i) {
-               pos += sizeof (gdouble);
-               ppc_stfd (code, i, -pos, ppc_sp);
-       }
-       pos += sizeof (gulong) * MONO_SAVED_GREGS;
-       ppc_store_multiple_regs (code, ppc_r13, ppc_sp, -pos);
-
+       /* store ret addr */
        ppc_mflr (code, ppc_r0);
        ppc_store_reg (code, ppc_r0, PPC_RET_ADDR_OFFSET, ppc_sp);
 
-       alloc_size = PPC_MINIMAL_STACK_SIZE + pos + 64;
-       // align to MONO_ARCH_FRAME_ALIGNMENT bytes
-       alloc_size += MONO_ARCH_FRAME_ALIGNMENT - 1;
-       alloc_size &= ~(MONO_ARCH_FRAME_ALIGNMENT - 1);
+       alloc_size = REG_SAVE_STACK_FRAME_SIZE;
 
        /* allocate stack frame and set link from sp in ctx */
        g_assert ((alloc_size & (MONO_ARCH_FRAME_ALIGNMENT-1)) == 0);
@@ -267,6 +277,8 @@ mono_arch_get_call_filter (void)
        ppc_load_reg_indexed (code, ppc_r0, ppc_r0, ppc_r0);
        ppc_store_reg_update (code, ppc_r0, -alloc_size, ppc_sp);
 
+       code = emit_save_saved_regs (code, alloc_size);
+
        /* restore all the regs from ctx (in r3), but not r1, the stack pointer */
        restore_regs_from_context (ppc_r3, ppc_r6, ppc_r7);
        /* call handler at eip (r4) and set the first arg with the exception (r5) */
@@ -277,17 +289,17 @@ mono_arch_get_call_filter (void)
        /* epilog */
        ppc_load_reg (code, ppc_r0, alloc_size + PPC_RET_ADDR_OFFSET, ppc_sp);
        ppc_mtlr (code, ppc_r0);
-       ppc_addic (code, ppc_sp, ppc_sp, alloc_size);
-       
+
        /* restore all the regs from the stack */
-       pos = 0;
+       pos = alloc_size;
        for (i = 31; i >= 14; --i) {
-               pos += sizeof (double);
-               ppc_lfd (code, i, -pos, ppc_sp);
+               pos -= sizeof (gdouble);
+               ppc_lfd (code, i, pos, ppc_sp);
        }
-       pos += sizeof (gulong) * MONO_SAVED_GREGS;
-       ppc_load_multiple_regs (code, ppc_r13, ppc_sp, -pos);
+       pos -= sizeof (gpointer) * MONO_SAVED_GREGS;
+       ppc_load_multiple_regs (code, ppc_r13, ppc_sp, pos);
 
+       ppc_addic (code, ppc_sp, ppc_sp, alloc_size);
        ppc_blr (code);
 
        g_assert ((code - start) < size);
@@ -339,32 +351,21 @@ static gpointer
 mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_name, gboolean rethrow)
 {
        guint8 *code;
-       int alloc_size, pos, i;
+       int alloc_size, pos;
 
        code = mono_ppc_create_pre_code_ftnptr (start);
 
-       /* save all the regs on the stack */
-       pos = 0;
-       for (i = 31; i >= 14; --i) {
-               pos += sizeof (gdouble);
-               ppc_stfd (code, i, -pos, ppc_sp);
-       }
-       pos += sizeof (gulong) * MONO_SAVED_GREGS;
-       ppc_store_multiple_regs (code, ppc_r13, ppc_sp, -pos);
-
+       /* store ret addr */
        ppc_mflr (code, ppc_r0);
        ppc_store_reg (code, ppc_r0, PPC_RET_ADDR_OFFSET, ppc_sp);
 
-       /* The 64 bytes here are for outgoing arguments and a bit of
-          spare.  We don't use it all, but it doesn't hurt. */
-       alloc_size = PPC_MINIMAL_STACK_SIZE + pos + 64;
-       // align to MONO_ARCH_FRAME_ALIGNMENT bytes
-       alloc_size += MONO_ARCH_FRAME_ALIGNMENT - 1;
-       alloc_size &= ~(MONO_ARCH_FRAME_ALIGNMENT - 1);
+       alloc_size = REG_SAVE_STACK_FRAME_SIZE;
 
        g_assert ((alloc_size & (MONO_ARCH_FRAME_ALIGNMENT-1)) == 0);
        ppc_store_reg_update (code, ppc_sp, -alloc_size, ppc_sp);
 
+       code = emit_save_saved_regs (code, alloc_size);
+
        //ppc_break (code);
        if (by_name) {
                ppc_mr (code, ppc_r5, ppc_r3);
@@ -384,10 +385,10 @@ mono_arch_get_throw_exception_generic (guint8 *start, int size, int by_name, gbo
        else
                ppc_mr (code, ppc_r4, ppc_r0); /* caller ip */
        /* pointer to the saved fp regs */
-       pos = alloc_size - sizeof (double) * MONO_SAVED_FREGS;
+       pos = alloc_size - sizeof (gdouble) * MONO_SAVED_FREGS;
        ppc_addi (code, ppc_r7, ppc_sp, pos);
        /* pointer to the saved int regs */
-       pos -= sizeof (gulong) * MONO_SAVED_GREGS;
+       pos -= sizeof (gpointer) * MONO_SAVED_GREGS;
        ppc_addi (code, ppc_r6, ppc_sp, pos);
        ppc_li (code, ppc_r8, rethrow);
 
index 24fb085fde1542223b27c4dddc62ad7a5a995221..936a9a1b6135b0c80d723bee28e9b46f785ee343 100644 (file)
@@ -3543,7 +3543,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        ppc_frsp (code, ins->dreg, ins->sreg1);
                        break;
                case OP_JMP: {
-                       int i, pos = 0;
+                       int i, pos;
                        
                        /*
                         * Keep in sync with mono_arch_emit_epilog
@@ -3566,10 +3566,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        code = emit_load_volatile_arguments (cfg, code);
 
                        if (ppc_is_imm16 (cfg->stack_usage)) {
-                               ppc_addic (code, ppc_sp, cfg->frame_reg, cfg->stack_usage);
+                               ppc_addic (code, ppc_r11, cfg->frame_reg, cfg->stack_usage);
                        } else {
                                ppc_load (code, ppc_r11, cfg->stack_usage);
-                               ppc_add (code, ppc_sp, cfg->frame_reg, ppc_r11);
+                               ppc_add (code, ppc_r11, cfg->frame_reg, ppc_r11);
                        }
                        if (!cfg->method->save_lmf) {
                                /*for (i = 31; i >= 14; --i) {
@@ -3578,16 +3578,17 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                                ppc_lfd (code, i, -pos, cfg->frame_reg);
                                        }
                                }*/
-                               /* FIXME: restore registers before changing ppc_sp */
+                               pos = 0;
                                for (i = 31; i >= 13; --i) {
                                        if (cfg->used_int_regs & (1 << i)) {
                                                pos += sizeof (gpointer);
-                                               ppc_load_reg_indexed (code, i, -pos, ppc_sp);
+                                               ppc_load_reg (code, i, -pos, ppc_r11);
                                        }
                                }
                        } else {
                                /* FIXME restore from MonoLMF: though this can't happen yet */
                        }
+                       ppc_mr (code, ppc_sp, ppc_r11);
                        mono_add_patch_info (cfg, (guint8*) code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, ins->inst_p0);
                        ppc_b (code, 0);
                        break;