Fri Nov 14 15:39:50 CET 2008 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Fri, 14 Nov 2008 14:42:42 +0000 (14:42 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Fri, 14 Nov 2008 14:42:42 +0000 (14:42 -0000)
* mini-ppc.h, mini-ppc.c: avoid using the red zone as some kernels are
buggy and will overwrite it.

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

mono/mini/ChangeLog
mono/mini/mini-ppc.c
mono/mini/mini-ppc.h

index 16b8b14b75ebf48a4419098131a338a3bb330f20..709d4361f4a93e6f11624d6dd94e65408fa63e31 100644 (file)
@@ -1,3 +1,9 @@
+
+Fri Nov 14 15:39:50 CET 2008 Paolo Molaro <lupus@ximian.com>
+
+       * mini-ppc.h, mini-ppc.c: avoid using the red zone as some kernels are
+       buggy and will overwrite it.
+
 2008-11-14  Zoltan Varga  <vargaz@gmail.com>
 
        * aot-compiler.c: Add functionality to emit local symbols to the elf writer.
index b87ab2f26b23aaaa73a1cf5a8e576343ca542e12..e791f2b7f2997e1b2a57cb92d345ff7125fff573 100644 (file)
@@ -1266,6 +1266,12 @@ mono_arch_allocate_vars (MonoCompile *m)
                curinst++;
        }
 
+       /* some storage for fp conversions */
+       offset += 8 - 1;
+       offset &= ~(8 - 1);
+       m->arch.fp_conv_var_offset = offset;
+       offset += 8;
+
        /* align the offset to 16 bytes */
        offset += 16 - 1;
        offset &= ~(16 - 1);
@@ -2027,11 +2033,17 @@ mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins)
                int msw_reg = mono_alloc_ireg (cfg);
                int adj_reg = mono_alloc_freg (cfg);
                int tmp_reg = mono_alloc_freg (cfg);
+               int basereg = cfg->frame_reg;
+               int offset = cfg->arch.fp_conv_var_offset;
                MONO_EMIT_NEW_ICONST (cfg, msw_reg, 0x43300000);
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, ppc_sp, -8, msw_reg);
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, ppc_sp, -4, ins->sreg1);
+               if (!ppc_is_imm16 (offset + 4)) {
+                       basereg = mono_alloc_ireg (cfg);
+                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IADD_IMM, basereg, cfg->frame_reg, offset);
+               }
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, basereg, offset, msw_reg);
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, basereg, offset + 4, ins->sreg1);
                MONO_EMIT_NEW_LOAD_R8 (cfg, adj_reg, &adjust_val);
-               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR8_MEMBASE, tmp_reg, ppc_sp, -8);
+               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR8_MEMBASE, tmp_reg, basereg, offset);
                MONO_EMIT_NEW_BIALU (cfg, OP_FSUB, ins->dreg, tmp_reg, adj_reg);
                ins->opcode = OP_NOP;
                break;
@@ -2044,12 +2056,18 @@ mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins)
                int xored = mono_alloc_ireg (cfg);
                int adj_reg = mono_alloc_freg (cfg);
                int tmp_reg = mono_alloc_freg (cfg);
+               int basereg = cfg->frame_reg;
+               int offset = cfg->arch.fp_conv_var_offset;
+               if (!ppc_is_imm16 (offset + 4)) {
+                       basereg = mono_alloc_ireg (cfg);
+                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IADD_IMM, basereg, cfg->frame_reg, offset);
+               }
                MONO_EMIT_NEW_ICONST (cfg, msw_reg, 0x43300000);
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, ppc_sp, -8, msw_reg);
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, basereg, offset, msw_reg);
                MONO_EMIT_NEW_BIALU_IMM (cfg, OP_XOR_IMM, xored, ins->sreg1, 0x80000000);
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, ppc_sp, -4, xored);
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, basereg, offset + 4, xored);
                MONO_EMIT_NEW_LOAD_R8 (cfg, adj_reg, (gpointer)&adjust_val);
-               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR8_MEMBASE, tmp_reg, ppc_sp, -8);
+               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR8_MEMBASE, tmp_reg, basereg, offset);
                MONO_EMIT_NEW_BIALU (cfg, OP_FSUB, ins->dreg, tmp_reg, adj_reg);
                if (ins->opcode == OP_ICONV_TO_R4)
                        MONO_EMIT_NEW_UNALU (cfg, OP_FCONV_TO_R4, ins->dreg, ins->dreg);
@@ -2058,8 +2076,14 @@ mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins)
        }
        case OP_CKFINITE: {
                int msw_reg = mono_alloc_ireg (cfg);
-               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, ppc_sp, -8, ins->sreg1);
-               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, msw_reg, ppc_sp, -8);
+               int basereg = cfg->frame_reg;
+               int offset = cfg->arch.fp_conv_var_offset;
+               if (!ppc_is_imm16 (offset + 4)) {
+                       basereg = mono_alloc_ireg (cfg);
+                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_IADD_IMM, basereg, cfg->frame_reg, offset);
+               }
+               MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, basereg, offset, ins->sreg1);
+               MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, msw_reg, basereg, offset);
                MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_FINITE, -1, msw_reg);
                MONO_EMIT_NEW_UNALU (cfg, OP_FMOVE, ins->dreg, ins->sreg1);
                ins->opcode = OP_NOP;
@@ -2420,10 +2444,18 @@ loop_start:
 static guchar*
 emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, gboolean is_signed)
 {
+       int offset = cfg->arch.fp_conv_var_offset;
        /* sreg is a float, dreg is an integer reg. ppc_f0 is used a scratch */
        ppc_fctiwz (code, ppc_f0, sreg);
-       ppc_stfd (code, ppc_f0, -8, ppc_sp);
-       ppc_lwz (code, dreg, -4, ppc_sp);
+       if (ppc_is_imm16 (offset + 4)) {
+               ppc_stfd (code, ppc_f0, offset, cfg->frame_reg);
+               ppc_lwz (code, dreg, offset + 4, cfg->frame_reg);
+       } else {
+               ppc_load (code, dreg, offset);
+               ppc_add (code, dreg, dreg, cfg->frame_reg);
+               ppc_stfd (code, ppc_f0, 0, dreg);
+               ppc_lwz (code, dreg, 4, dreg);
+       }
        if (!is_signed) {
                if (size == 1)
                        ppc_andid (code, dreg, dreg, 0xff);
@@ -3381,6 +3413,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                                ppc_lfd (code, i, -pos, cfg->frame_reg);
                                        }
                                }*/
+                               /* FIXME: restore registers before changing ppc_sp */
                                for (i = 31; i >= 13; --i) {
                                        if (cfg->used_int_regs & (1 << i)) {
                                                pos += sizeof (gulong);
index ddac0c811315771943c92df9a26c9746217f728f..24b2efca3bb0d47a86726b95287c563a0c4ca938 100644 (file)
@@ -44,6 +44,7 @@ typedef struct {
 } MonoContext;
 
 typedef struct MonoCompileArch {
+       int fp_conv_var_offset;
 } MonoCompileArch;
 
 #define MONO_ARCH_EMULATE_FCONV_TO_I8 1