]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/25127 (internal compiler error: in rs6000_emit_prologue, at config/rs600...
authorGeoffrey Keating <geoffk@gcc.gnu.org>
Thu, 25 Jan 2007 20:32:06 +0000 (20:32 +0000)
committerGeoffrey Keating <geoffk@gcc.gnu.org>
Thu, 25 Jan 2007 20:32:06 +0000 (20:32 +0000)
2007-01-24  Geoffrey Keating  <geoffk@apple.com>

PR 25127
* config/rs6000/rs6000.c (first_altivec_reg_to_save): On Darwin,
save Altivec registers in an eh_return function.
(compute_vrsave_mask): Likewise.
(rs6000_stack_info): Correct AIX/Darwin stack alignment computation
for saving Altivec registers.
(rs6000_emit_prologue): Don't allocate stack twice in
eh_return function.  Correct expected value of altivec_save_offset
when using save_world.  Describe save of R0 to stack when using
save_world.  Describe stack pointer adjustment when using
save_world.  Remove duplicated eh_return parameter register saving.
Update sp_offset variable after save_world.
* config/rs6000/t-darwin (LIB2FUNCS_STATIC_EXTRA): Remove
darwin-world.asm.
(LIB2FUNCS_EXTRA): Add darwin-world.asm.
* config/rs6000/darwin.h (SUBTARGET_OVERRIDE_OPTIONS): -m64
implies Altivec.

Index: gcc/testsuite/ChangeLog
2007-01-24  Geoffrey Keating  <geoffk@apple.com>

* gcc.target/powerpc/darwin-ehreturn-1.c: New.
* g++.dg/eh/simd-2.C: Also run on Darwin.
* g++.dg/eh/simd-3.C: New.
* g++.dg/eh/simd-4.C: New.

From-SVN: r121184

gcc/ChangeLog
gcc/config/rs6000/darwin.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/t-darwin
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/eh/simd-2.C
gcc/testsuite/g++.dg/eh/simd-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/eh/simd-4.C [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/darwin-ehreturn-1.c [new file with mode: 0644]

index f9af580517f7af0c9beb46135990befd44074c8a..0791bafb57eb998611fe29864f8d0dbf2a364d96 100644 (file)
@@ -1,3 +1,23 @@
+2007-01-25  Geoffrey Keating  <geoffk@apple.com>
+
+       PR 25127
+       * config/rs6000/rs6000.c (first_altivec_reg_to_save): On Darwin,
+       save Altivec registers in an eh_return function.
+       (compute_vrsave_mask): Likewise.
+       (rs6000_stack_info): Correct AIX/Darwin stack alignment computation
+       for saving Altivec registers.
+       (rs6000_emit_prologue): Don't allocate stack twice in
+       eh_return function.  Correct expected value of altivec_save_offset
+       when using save_world.  Describe save of R0 to stack when using
+       save_world.  Describe stack pointer adjustment when using
+       save_world.  Remove duplicated eh_return parameter register saving.
+       Update sp_offset variable after save_world.
+       * config/rs6000/t-darwin (LIB2FUNCS_STATIC_EXTRA): Remove
+       darwin-world.asm.
+       (LIB2FUNCS_EXTRA): Add darwin-world.asm.
+       * config/rs6000/darwin.h (SUBTARGET_OVERRIDE_OPTIONS): -m64
+       implies Altivec.
+
 2007-01-25  Steve Ellcey  <sje@cup.hp.com>
 
        * config.gcc (ia64*-*-hpux*): Make posix threads the default.
 
 2007-01-25  Razya Ladelsky  <razya@il.ibm.com>
 
-        * ipa-cp.c (ipcp_insert_stage, ipcp_driver): Support for SSA. 
-          (ipcp_driver): Change to static definition. 
-         Add dumping of the ifunctions.
-          (constant_val_insert): Remove unused parameter. Support for SSA.
-          (ipcp_propagate_const): Support for SSA.
-          (ipcp_profile_bb_print): Print only analyzed nodes.
-          (ipcp_replace_map_create): Remove support for Fortran constant 
-         for now.
-          * ipa-prop.c (ipa_method_modify_stmt, 
-         ipa_callsite_compute_param): Support for SSA.
-          * ipa-prop.h (ipcp_driver): Remove declaration.
-          (IS_VALID_TREE_MAP_INDEX): Add define.
+       * ipa-cp.c (ipcp_insert_stage, ipcp_driver): Support for SSA. 
+       (ipcp_driver): Change to static definition. 
+       Add dumping of the ifunctions.
+       (constant_val_insert): Remove unused parameter. Support for SSA.
+       (ipcp_propagate_const): Support for SSA.
+       (ipcp_profile_bb_print): Print only analyzed nodes.
+       (ipcp_replace_map_create): Remove support for Fortran constant 
+       for now.
+       * ipa-prop.c (ipa_method_modify_stmt, 
+       ipa_callsite_compute_param): Support for SSA.
+       * ipa-prop.h (ipcp_driver): Remove declaration.
+       (IS_VALID_TREE_MAP_INDEX): Add define.
+
 2007-01-24  Geoffrey Keating  <geoffk@apple.com>
 
        * unwind-dw2.c (execute_stack_op): Handle DW_OP_swap.
index ed6e42afa587fd998d7032a0dcaf4fb19d69d58c..28134f922db8f4c6b2e4a1aca852b016e994409a 100644 (file)
@@ -91,11 +91,19 @@ do {                                                                        \
       target_flags |= MASK_POWERPC64;                                  \
       warning (0, "-m64 requires PowerPC64 architecture, enabling");   \
     }                                                                  \
-  if (flag_mkernel)                                                     \
+  if (flag_mkernel)                                                    \
     {                                                                  \
       rs6000_default_long_calls = 1;                                   \
       target_flags |= MASK_SOFT_FLOAT;                                 \
     }                                                                  \
+                                                                       \
+  /* Make -m64 imply -maltivec.  Darwin's 64-bit ABI includes          \
+     Altivec.  */                                                      \
+  if (!flag_mkernel && !flag_apple_kext                                        \
+      && TARGET_64BIT                                                  \
+      && ! (target_flags_explicit & MASK_ALTIVEC))                     \
+    target_flags |= MASK_ALTIVEC;                                      \
+                                                                       \
   /* Unless the user (not the configurer) has explicitly overridden    \
      it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to   \
      G4 unless targetting the kernel.  */                              \
index f72fde34ffc0a05a527e34997a17f7223d2a0b32..dbb1f550f9727f3e475497b473b1c79261744876 100644 (file)
@@ -13020,6 +13020,13 @@ first_altivec_reg_to_save (void)
   if (! TARGET_ALTIVEC_ABI)
     return LAST_ALTIVEC_REGNO + 1;
 
+  /* On Darwin, the unwind routines are compiled without
+     TARGET_ALTIVEC, and use save_world to save/restore the 
+     altivec registers when necessary.  */
+  if (DEFAULT_ABI == ABI_DARWIN && current_function_calls_eh_return
+      && ! TARGET_ALTIVEC)
+    return FIRST_ALTIVEC_REGNO + 20;
+
   /* Find lowest numbered live register.  */
   for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
     if (regs_ever_live[i])
@@ -13037,6 +13044,13 @@ compute_vrsave_mask (void)
 {
   unsigned int i, mask = 0;
 
+  /* On Darwin, the unwind routines are compiled without
+     TARGET_ALTIVEC, and use save_world to save/restore the 
+     call-saved altivec registers when necessary.  */
+  if (DEFAULT_ABI == ABI_DARWIN && current_function_calls_eh_return
+      && ! TARGET_ALTIVEC)
+    mask |= 0xFFF;
+
   /* First, find out if we use _any_ altivec registers.  */
   for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
     if (regs_ever_live[i])
@@ -13381,7 +13395,7 @@ rs6000_stack_info (void)
          /* Align stack so vector save area is on a quadword boundary.  */
          if (info_ptr->altivec_size != 0)
            info_ptr->altivec_padding_size
-             = 16 - (-info_ptr->vrsave_save_offset % 16);
+             = (-info_ptr->vrsave_save_offset) % 16;
          else
            info_ptr->altivec_padding_size = 0;
 
@@ -14529,7 +14543,8 @@ rs6000_emit_prologue (void)
                        || cfun->machine->ra_need_lr);
 
   /* For V.4, update stack before we do any saving and set back pointer.  */
-  if (info->push_p
+  if (! WORLD_SAVE_P (info)
+      && info->push_p
       && (DEFAULT_ABI == ABI_V4
          || current_function_calls_eh_return))
     {
@@ -14554,11 +14569,13 @@ rs6000_emit_prologue (void)
       int i, j, sz;
       rtx treg;
       rtvec p;
+      rtx reg0;
 
       /* save_world expects lr in r0. */
+      reg0 = gen_rtx_REG (Pmode, 0);
       if (info->lr_save_p)
        {
-         insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
+         insn = emit_move_insn (reg0,
                                 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
          RTX_FRAME_RELATED_P (insn) = 1;
        }
@@ -14575,7 +14592,7 @@ rs6000_emit_prologue (void)
                  && (!current_function_calls_eh_return
                       || info->ehrd_offset == -432)
                  && info->vrsave_save_offset == -224
-                 && info->altivec_save_offset == (-224 -16 -192));
+                 && info->altivec_save_offset == -416);
 
       treg = gen_rtx_REG (SImode, 11);
       emit_move_insn (treg, GEN_INT (-info->total_size));
@@ -14584,7 +14601,7 @@ rs6000_emit_prologue (void)
         in R11.  It also clobbers R12, so beware!  */
 
       /* Preserve CR2 for save_world prologues */
-      sz = 6;
+      sz = 5;
       sz += 32 - info->first_gp_reg_save;
       sz += 64 - info->first_fp_reg_save;
       sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
@@ -14639,29 +14656,26 @@ rs6000_emit_prologue (void)
 
        RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
       }
-      /* Prevent any attempt to delete the setting of r0 and treg!  */
-      RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 0));
-      RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, treg);
-      RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode, sp_reg_rtx);
+      /* Explain about use of R0.  */
+      if (info->lr_save_p)
+       {
+         rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+                                  GEN_INT (info->lr_save_offset
+                                           + sp_offset));
+         rtx mem = gen_frame_mem (reg_mode, addr);
+         
+         RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
+       }
+      /* Explain what happens to the stack pointer.  */
+      {
+       rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
+       RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
+      }
 
       insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
       rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
-                           NULL_RTX, NULL_RTX);
-
-      if (current_function_calls_eh_return)
-       {
-         unsigned int i;
-         for (i = 0; ; ++i)
-           {
-             unsigned int regno = EH_RETURN_DATA_REGNO (i);
-             if (regno == INVALID_REGNUM)
-               break;
-             emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
-                              info->ehrd_offset + sp_offset
-                              + reg_size * (int) i,
-                              info->total_size);
-           }
-       }
+                           treg, GEN_INT (-info->total_size));
+      sp_offset = info->total_size;
     }
 
   /* Save AltiVec registers if needed.  */
@@ -14890,7 +14904,7 @@ rs6000_emit_prologue (void)
 
   /* ??? There's no need to emit actual instructions here, but it's the
      easiest way to get the frame unwind information emitted.  */
-  if (!WORLD_SAVE_P (info) && current_function_calls_eh_return)
+  if (current_function_calls_eh_return)
     {
       unsigned int i, regno;
 
index b742f763c9aecf4384c95578ba3cfec9dc23e154..0a31bd76d7de894a32ee0e1b351fbc651df339b0 100644 (file)
@@ -1,12 +1,12 @@
 LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-tramp.asm \
        $(srcdir)/config/rs6000/ppc64-fp.c \
        $(srcdir)/config/darwin-64.c \
-       $(srcdir)/config/rs6000/darwin-ldouble.c
+       $(srcdir)/config/rs6000/darwin-ldouble.c \
+       $(srcdir)/config/rs6000/darwin-world.asm
 
 LIB2FUNCS_STATIC_EXTRA = \
        $(srcdir)/config/rs6000/darwin-fpsave.asm  \
-       $(srcdir)/config/rs6000/darwin-vecsave.asm  \
-       $(srcdir)/config/rs6000/darwin-world.asm
+       $(srcdir)/config/rs6000/darwin-vecsave.asm
 
 DARWIN_EXTRA_CRT_BUILD_CFLAGS = -mlongcall -mmacosx-version-min=10.4
 
index a769a06195561b954672e1a795ff26845d98fc36..afbd22a512c27203c31f72e31ac5b8340dd321fc 100644 (file)
@@ -1,3 +1,10 @@
+2007-01-24  Geoffrey Keating  <geoffk@apple.com>
+
+       * gcc.target/powerpc/darwin-ehreturn-1.c: New.
+       * g++.dg/eh/simd-2.C: Also run on Darwin.
+       * g++.dg/eh/simd-3.C: New.
+       * g++.dg/eh/simd-4.C: New.
+
 2007-01-25  Richard Guenther  <rguenther@suse.de>
 
        * gcc.dg/tree-prof/tree-prof.exp: Define _PROFILE_GENERATE
@@ -6,7 +13,7 @@
 
 2007-01-25  Razya Ladelsky  <razya@il.ibm.com>
 
-        * gcc.dg/ipa/ipa-1.c: Update scan tree dump.
+       * gcc.dg/ipa/ipa-1.c: Update scan tree dump.
        * gcc.dg/ipa/ipa-2.c: Update scan tree dump.
        * gcc.dg/ipa/ipa-3.c: Update scan tree dump.
        * gcc.dg/ipa/ipa-4.c: Update scan tree dump.
index 52720a4b5eefae177588c3dc03aefafd7c3f68c1..e2af86636acbe6d922f22a2bcc4388a709e080c6 100644 (file)
@@ -4,6 +4,7 @@
 // { dg-options "-O -w" { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
 // { dg-options "-O -w" { target powerpc*-*-* } }
 // { dg-options "-O -w -maltivec" { target { powerpc*-*-linux* && powerpc_altivec_ok } } }
+// { dg-options "-O -w -maltivec" { target { powerpc*-*-darwin* && powerpc_altivec_ok } } }
 // { dg-xfail-if "" { "powerpc-*-eabispe*" "powerpc-ibm-aix*" } { "*" } { "" } }
 // { dg-do run }
 
diff --git a/gcc/testsuite/g++.dg/eh/simd-3.C b/gcc/testsuite/g++.dg/eh/simd-3.C
new file mode 100644 (file)
index 0000000..5ac75c9
--- /dev/null
@@ -0,0 +1,65 @@
+// { dg-options "-O" }
+// { dg-options "-O -maltivec" { target { powerpc*-*-darwin* && powerpc_altivec_ok } } }
+// { dg-do run }
+
+#include <cstdlib>
+#include <cstring>
+
+typedef int __attribute__((vector_size(16))) v;
+
+v vv[32];
+volatile v vt = { 1, 2, 3, 4 };
+
+void clobber_vrs(void) { };
+
+void (*volatile fp)() = clobber_vrs;
+
+void thrower(void)
+{
+  v v00 = vv[ 0];
+  v v01 = vv[ 1];
+  v v02 = vv[ 2];
+  v v03 = vv[ 3];
+  v v04 = vv[ 4];
+  v v05 = vv[ 5];
+  v v06 = vv[ 6];
+  v v07 = vv[ 7];
+  v v08 = vv[ 8];
+  v v09 = vv[ 9];
+  v v10 = vv[10];
+  v v11 = vv[11];
+  v v12 = vv[12];
+
+  fp();
+
+  vv[ 0] = v00;
+  vv[ 1] = v01;
+  vv[ 2] = v02;
+  vv[ 3] = v03;
+  vv[ 4] = v04;
+  vv[ 5] = v05;
+  vv[ 6] = v06;
+  vv[ 7] = v07;
+  vv[ 8] = v08;
+  vv[ 9] = v09;
+  vv[10] = v10;
+  vv[11] = v11;
+  vv[12] = v12;
+
+  throw 3;
+}
+
+v v2;
+
+int main(void)
+{
+  v v1 = vt;
+  try {
+    thrower();
+  } catch (int x) {
+  }
+  v2 = v1;
+  if (memcmp (&v2, (v *)&vt, sizeof (v2)) != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/g++.dg/eh/simd-4.C b/gcc/testsuite/g++.dg/eh/simd-4.C
new file mode 100644 (file)
index 0000000..2552fb1
--- /dev/null
@@ -0,0 +1,68 @@
+/* { dg-do run { target powerpc*-*-darwin* } } */
+/* { dg-options "-fexceptions -fnon-call-exceptions -O -maltivec" } */
+
+#include <cstdlib>
+#include <cstring>
+#include <signal.h>
+
+typedef int __attribute__((vector_size(16))) v;
+
+v vv[32];
+volatile v vt = { 1, 2, 3, 4 };
+
+void clobber_vrs(void) { };
+
+void (*volatile fp)() = clobber_vrs;
+
+void thrower(int sig)
+{
+  v v00 = vv[ 0];
+  v v01 = vv[ 1];
+  v v02 = vv[ 2];
+  v v03 = vv[ 3];
+  v v04 = vv[ 4];
+  v v05 = vv[ 5];
+  v v06 = vv[ 6];
+  v v07 = vv[ 7];
+  v v08 = vv[ 8];
+  v v09 = vv[ 9];
+  v v10 = vv[10];
+  v v11 = vv[11];
+  v v12 = vv[12];
+
+  fp();
+
+  vv[ 0] = v00;
+  vv[ 1] = v01;
+  vv[ 2] = v02;
+  vv[ 3] = v03;
+  vv[ 4] = v04;
+  vv[ 5] = v05;
+  vv[ 6] = v06;
+  vv[ 7] = v07;
+  vv[ 8] = v08;
+  vv[ 9] = v09;
+  vv[10] = v10;
+  vv[11] = v11;
+  vv[12] = v12;
+
+  throw 3;
+}
+
+v v2;
+
+int main(void)
+{
+  v v1 = vt;
+  if (signal (SIGBUS, thrower) == SIG_ERR)
+    abort ();
+  try {
+    *(volatile int *)0 = 0;
+    abort ();
+  } catch (int x) {
+  }
+  v2 = v1;
+  if (memcmp (&v2, (v *)&vt, sizeof (v2)) != 0)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/darwin-ehreturn-1.c b/gcc/testsuite/gcc.target/powerpc/darwin-ehreturn-1.c
new file mode 100644 (file)
index 0000000..71ee094
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile { target powerpc*-*-darwin* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-mcpu=G3 -funwind-tables" } */
+/* { dg-final { scan-assembler "bl save_world" } } */
+/* { dg-final { scan-assembler ".byte\t0x6b" } } */
+
+/* Verify that on Darwin, even with -mcpu=G3, __builtin_eh_return
+   saves Altivec registers using save_world, and reports their
+   location in its EH information.  */
+
+long offset;
+void *handler;
+
+extern void setup_offset(void);
+
+void foo(void)
+{
+  __builtin_unwind_init ();
+  setup_offset();
+  __builtin_eh_return (offset, handler);
+}