Fri Nov 21 12:52:23 CET 2008 Paolo Molaro <lupus@ximian.com>
authorPaolo Molaro <lupus@oddwiz.org>
Fri, 21 Nov 2008 12:23:03 +0000 (12:23 -0000)
committerPaolo Molaro <lupus@oddwiz.org>
Fri, 21 Nov 2008 12:23:03 +0000 (12:23 -0000)
* mini-ppc.c: remove negative stack references in epilog
for platforms that don't support the red zone.

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

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

index 0afeb98503fd125084b877948f8b4abbdff3f9f3..b9cf3a3b4ae81d2de4492df2dfff40b529adcc1f 100644 (file)
@@ -1,3 +1,9 @@
+
+Fri Nov 21 12:52:23 CET 2008 Paolo Molaro <lupus@ximian.com>
+
+       * mini-ppc.c: remove negative stack references in epilog
+       for platforms that don't support the red zone.
+
 2008-11-21  Mark Probst  <mark.probst@gmail.com>
 
        * mini-ppc64.h, cpu-ppc64.md: Fixed caller/callee saved floating
index da50ef6bcfdba6dfbe4ccd131560a3a5383d5e2b..dc908f7a50318a7fd3a415300d1062446268bf4a 100644 (file)
@@ -4270,24 +4270,40 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                        ppc_mtlr (code, ppc_r0);
                }
                if (ppc_is_imm16 (cfg->stack_usage)) {
-                       ppc_addic (code, ppc_sp, cfg->frame_reg, cfg->stack_usage);
+                       int offset = cfg->stack_usage;
+                       for (i = 13; i <= 31; i++) {
+                               if (cfg->used_int_regs & (1 << i))
+                                       offset -= sizeof (gulong);
+                       }
+                       if (cfg->frame_reg != ppc_sp)
+                               ppc_mr (code, ppc_r11, cfg->frame_reg);
+                       /* note r31 (possibly the frame register) is restored last */
+                       for (i = 13; i <= 31; i++) {
+                               if (cfg->used_int_regs & (1 << i)) {
+                                       ppc_lwz (code, i, offset, cfg->frame_reg);
+                                       offset += sizeof (gulong);
+                               }
+                       }
+                       if (cfg->frame_reg != ppc_sp)
+                               ppc_addic (code, ppc_sp, ppc_r11, cfg->stack_usage);
+                       else
+                               ppc_addic (code, ppc_sp, ppc_sp, cfg->stack_usage);
                } else {
                        ppc_load (code, ppc_r11, cfg->stack_usage);
-                       ppc_add (code, ppc_sp, cfg->frame_reg, ppc_r11);
-               }
-
-               /*for (i = 31; i >= 14; --i) {
-                       if (cfg->used_float_regs & (1 << i)) {
-                               pos += sizeof (double);
-                               ppc_lfd (code, i, -pos, ppc_sp);
-                       }
-               }*/
-               for (i = 31; i >= 13; --i) {
-                       if (cfg->used_int_regs & (1 << i)) {
-                               pos += sizeof (gulong);
-                               ppc_lwz (code, i, -pos, ppc_sp);
+                       if (cfg->used_int_regs) {
+                               ppc_add (code, ppc_r11, cfg->frame_reg, ppc_r11);
+                               for (i = 31; i >= 13; --i) {
+                                       if (cfg->used_int_regs & (1 << i)) {
+                                               pos += sizeof (gulong);
+                                               ppc_lwz (code, i, -pos, ppc_r11);
+                                       }
+                               }
+                               ppc_mr (code, ppc_sp, ppc_r11);
+                       } else {
+                               ppc_add (code, ppc_sp, cfg->frame_reg, ppc_r11);
                        }
                }
+
        }
        ppc_blr (code);