While trying to track down the vector unwind problems on ppc-darwin, I made some tidy-ups for "save_world()". In the end, that was not where the main problem, lay - but I did find a few things wrong there on the way - they should be fixed, even if there's no specific bug filed at present.

I'm also attaching a second patch which is purely cosmetic white-space/ comment tidies I'd also like to apply.

checked on powerpc-darwin{8-G4,9-G5} and crosses to powerpc-eabisim and powerpc-ibm-aix6.1.3.0

===

In due course, we should be able to split the save_world_p logic out of rs6000_emit_{pro,epi}logue.

The attached patch moves also one step nearer that - by doing the VRSave changes within the save_world() routine when that is in use - - actually, this is necessary really - if one remembers that vec code that should only be present in the prologue when the target cpu is a G4 or better.

OK for trunk?
Iain

gcc:

        * config/rs6000/rs6000.c (first_altivec_reg_to_save): Amend comment.
        (compute_vrsave_mask): Likewise.
        (rs6000_emit_prologue): Move update of VRSave mask to save_world()
        when that is in use.

libgcc:

* config/rs6000/darwin-world.S (toplevel): Make it clear that this function is
        not used for PPC64.  (save_world): Amend comments.  Update the VRsave
        mask to reflect the saved regs.
        (rest_world): Update comments, do not  clobber r10, do not use r8.
        (eh_rest_world_r10): Amend comments, do not use r8.
        (rest_world_eh_r7r8): Make local, move restore of CR and target address
        to end of routine, do not use r8.

===

part 2.

libgcc:

        * config/rs6000/darwin-world.S: Amend whitespace and comments.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 181818)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -17284,9 +17284,10 @@ 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.  */
+  /* When generating code for earlier versions of Darwin, which might run on
+     hardware with or without Altivec, we use out-of-line save/restores in
+     function prologues/epilogues that require it.  These routines determine
+     whether to save/restore Altivec at runtime.  */
   if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
       && ! TARGET_ALTIVEC)
     return FIRST_ALTIVEC_REGNO + 20;
@@ -17308,9 +17309,10 @@ 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.  */
+/* When generating code for earlier versions of Darwin, which might run on
+   hardware with or without Altivec, we use out-of-line save/restores in
+   function prologues/epilogues that require it.  These routines determine
+   whether to save/restore Altivec at runtime.  */
   if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
       && ! TARGET_ALTIVEC)
     mask |= 0xFFF;
@@ -19902,7 +19909,9 @@ rs6000_emit_prologue (void)
      used in this function, and do the corresponding magic in the
      epilogue.  */
 
-  if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
+  if (!WORLD_SAVE_P (info)
+      && TARGET_ALTIVEC
+      && TARGET_ALTIVEC_VRSAVE
       && info->vrsave_mask != 0)
     {
       rtx reg, mem, vrsave;
@@ -19918,15 +19927,12 @@ rs6000_emit_prologue (void)
       else
         emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
 
-      if (!WORLD_SAVE_P (info))
-        {
-          /* Save VRSAVE.  */
-          offset = info->vrsave_save_offset + sp_offset;
-          mem = gen_frame_mem (SImode,
-                               gen_rtx_PLUS (Pmode, frame_reg_rtx,
-                                             GEN_INT (offset)));
-          insn = emit_move_insn (mem, reg);
-        }
+      /* Save VRSAVE.  */
+      offset = info->vrsave_save_offset + sp_offset;
+      mem = gen_frame_mem (SImode,
+                          gen_rtx_PLUS (Pmode, frame_reg_rtx, 
+                                        GEN_INT (offset)));
+      insn = emit_move_insn (mem, reg);
 
       /* Include the registers in the mask.  */
       emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
Index: libgcc/config/rs6000/darwin-world.S
===================================================================
--- libgcc/config/rs6000/darwin-world.S (revision 181818)
+++ libgcc/config/rs6000/darwin-world.S (working copy)
@@ -24,6 +24,8 @@
  * <http://www.gnu.org/licenses/>.
  */ 
 
+#ifndef __ppc64__
+
        .machine ppc7400
 .data
        .align 2
@@ -33,12 +35,7 @@
 .non_lazy_symbol_pointer
 L_has_vec$non_lazy_ptr:
        .indirect_symbol __cpu_has_altivec
-#ifdef __ppc64__
-       .quad   0
-#else
        .long   0
-#endif
-
 #else
 
 /* For static, "pretend" we have a non-lazy-pointer.  */
@@ -57,12 +54,11 @@ L_has_vec$non_lazy_ptr:
    provided by the System Framework to determine this.)
 
    SAVE_WORLD takes R0 (the caller`s caller`s return address) and R11
-   (the stack frame size) as parameters.  It returns VRsave in R0 if
-   we`re on a CPU with vector regs.
+   (the stack frame size) as parameters.  It returns the updated VRsave
+   in R0 if we`re on a CPU with vector regs.
 
-   With gcc3, we now need to save and restore CR as well, since gcc3's
-   scheduled prologs can cause comparisons to be moved before calls to
-   save_world!
+   For gcc3 onward, we need to save and restore CR as well, since scheduled
+   prologs can cause comparisons to be moved before calls to save_world.
 
    USES: R0 R11 R12  */
 
@@ -143,69 +139,62 @@ L$saveVMX:
        stvx v30,r11,r12
        mfspr r0,VRsave
        li r11,-16
-       stvx v31,r11,r12
-                               /* VRsave lives at -224(R1)  */
-       stw r0,0(r12)
+       stvx v31,r11,r12        
+       stw r0,0(r12)           /* VRsave lives at -224(R1).  */
+       ori r0,r0,0xfff         /* We just saved these.  */
+       mtspr VRsave,r0
        blr
 
+/* rest_world  is jumped to, not called, so no need to worry about LR.
+   clobbers R0, R7, R11 and R12.  This just undoes the work done above.  */
 
+       .private_extern rest_world
+rest_world:
+                               
+       lwz r11, 0(r1)          /* Pickup previous SP  */
+       li r7, 0                /* Stack offset is zero, r10 is ignored.  */
+       b Lrest_world_eh_r7r8
+
 /* eh_rest_world_r10 is jumped to, not called, so no need to worry about LR.
    R10 is the C++ EH stack adjust parameter, we return to the caller`s caller.
 
-   USES: R0 R10 R11 R12   and R7 R8
-   RETURNS: C++ EH Data registers (R3 - R6.)
+   clobbers: R0, R7, R11 and R12
+   uses    : R10
+   RETURNS : C++ EH Data registers (R3 - R6).  */
 
-   We now set up R7/R8 and jump to rest_world_eh_r7r8.
-
-   rest_world doesn't use the R10 stack adjust parameter, nor does it
-   pick up the R3-R6 exception handling stuff.  */
-
-.private_extern rest_world
-rest_world:
-                               /* Pickup previous SP  */
-       lwz r11, 0(r1)
-       li r7, 0
-       lwz r8, 8(r11)
-       li r10, 0
-       b rest_world_eh_r7r8
-
-.private_extern eh_rest_world_r10
+       .private_extern eh_rest_world_r10
 eh_rest_world_r10:
-                               /* Pickup previous SP  */
-       lwz r11, 0(r1)
-       mr  r7,r10
-       lwz r8, 8(r11)
-                       /* pickup the C++ EH data regs (R3 - R6.)  */
+                               
+       lwz r11, 0(r1)          /* Pickup previous SP  */
+       mr  r7,r10              /* Stack offset.  */
+       
+       /* pickup the C++ EH data regs (R3 - R6.)  */
        lwz r6,-420(r11)
        lwz r5,-424(r11)
        lwz r4,-428(r11)
        lwz r3,-432(r11)
 
-       b rest_world_eh_r7r8
+       /* Fall through to Lrest_world_eh_r7r8.  */
 
-/* rest_world_eh_r7r8 is jumped to -- not called! -- when we're doing
-   the exception-handling epilog.  R7 contains the offset to add to
-   the SP, and R8 contains the 'real' return address.
+/* When we are doing the exception-handling epilog, R7 contains the offset to
+   add to the SP.
 
-   USES: R0 R11 R12  [R7/R8]
-   RETURNS: C++ EH Data registers (R3 - R6.)  */
+   clobbers: R0, R11 and R12
+   uses    : R7.  */
 
-rest_world_eh_r7r8:
+Lrest_world_eh_r7r8:
+       /* See if we have Altivec.  */
        bcl 20,31,Lr7r8$pb
 Lr7r8$pb: mflr r12
-       lwz r11,0(r1)
-                               /* R11 := previous SP  */
+
        addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Lr7r8$pb)
        lwz r12,lo16(L_has_vec$non_lazy_ptr-Lr7r8$pb)(r12)
-       lwz r0,4(r11)
-                               /* R0 := old CR  */
-       lwz r12,0(r12)
-                               /* R12 := HAS_VEC  */
-       mtcr r0 
+       lwz r12,0(r12)          /* R12 := HAS_VEC  */
        cmpwi r12,0
        lmw r13,-220(r11)
        beq L.rest_world_fp_eh
-                               /* restore VRsave and V20..V31  */
+
+       /* We have Altivec, restore VRsave and V20..V31  */
        lwz r0,-224(r11)
        li r12,-416
        mtspr VRsave,r0
@@ -234,6 +223,7 @@ Lr7r8$pb: mflr r12
        lvx v31,r11,r12
 
 L.rest_world_fp_eh:
+       lwz r0,4(r11)           /* recover saved CR  */
        lfd f14,-144(r11)
        lfd f15,-136(r11)
        lfd f16,-128(r11)
@@ -251,9 +241,23 @@ L.rest_world_fp_eh:
        lfd f28,-32(r11)
        lfd f29,-24(r11)
        lfd f30,-16(r11)
-                       /* R8 is the exception-handler's address  */
-       mtctr r8
-       lfd f31,-8(r11)
-                       /* set SP to original value + R7 offset  */
-       add r1,r11,r7
+       mtcr r0                 /* restore the saved cr.  */
+       lwz r0, 8(r11)          /* Pick up the 'real' return address.  */
+       lfd f31,-8(r11)         
+       mtctr r0                /* exception-handler ret. address  */
+       add r1,r11,r7           /* set SP to original value + R7 offset  */
        bctr
+
+#else /* ... ppc64 we should never be called for this ... */
+       .machine ppc64
+
+       .private_extern save_world
+save_world:
+       trap
+
+       .private_extern eh_rest_world_r10
+eh_rest_world_r10:
+       trap
+
+#endif
+       /* Done.  */


--- libgcc/config/rs6000/darwin-world.S-1       2011-11-30 14:04:49.000000000 
+0000
+++ libgcc/config/rs6000/darwin-world.S-ids     2011-11-26 17:19:25.000000000 
+0000
@@ -32,7 +32,7 @@
 
 #ifdef __DYNAMIC__
 
-.non_lazy_symbol_pointer
+       .non_lazy_symbol_pointer
 L_has_vec$non_lazy_ptr:
        .indirect_symbol __cpu_has_altivec
        .long   0
@@ -45,8 +45,7 @@ L_has_vec$non_lazy_ptr:
 
 #endif
 
-
-.text
+       .text
        .align 2
 
 /* save_world and rest_world save/restore F14-F31 and possibly V20-V31
@@ -62,7 +61,7 @@ L_has_vec$non_lazy_ptr:
 
    USES: R0 R11 R12  */
 
-.private_extern save_world
+       .private_extern save_world
 save_world:
        stw r0,8(r1)
        mflr r0
@@ -72,10 +71,10 @@ Ls$pb:      mflr r12
        lwz r12,lo16(L_has_vec$non_lazy_ptr-Ls$pb)(r12)
        mtlr r0
        lwz r12,0(r12)
-                               /* grab CR  */
-       mfcr r0 
-                               /* test HAS_VEC  */
-       cmpwi r12,0
+                               
+       mfcr r0                 /* grab incoming CR  */
+       cmpwi r12,0             /* test HAS_VEC  */
+       /* Save the FPRs...  */
        stfd f14,-144(r1)
        stfd f15,-136(r1)
        stfd f16,-128(r1)
@@ -94,25 +93,22 @@ Ls$pb:      mflr r12
        stfd f29,-24(r1)
        stfd f30,-16(r1)
        stfd f31,-8(r1)
+       /* ... and the GPRs ... */
        stmw r13,-220(r1)
-                               /* stash CR  */
+       /* ... the CR  */
        stw r0,4(r1)
-                               /* set R12 pointing at Vector Reg save area  */
-       addi r12,r1,-224
-                               /* allocate stack frame  */
-       stwux r1,r1,r11
-                               /* ...but return if HAS_VEC is zero   */
-       bne+ L$saveVMX
-                               /* Not forgetting to restore CR.  */
-       mtcr r0
+       addi r12,r1,-224        /* set R12 pointing at Vector Reg save area  */
+       stwux r1,r1,r11         /* allocate stack frame  */
+       bne+ L$saveVMX          /* ...but return if HAS_VEC is zero   */
+       mtcr r0                 /* Not forgetting to restore CR.  */
        blr
 
 L$saveVMX:
-                               /* We're saving Vector regs too.  */
-                               /* Restore CR from R0.  No More Branches!  */
-       mtcr r0
+       /* We are saving Vector regs too.  */
+
+       mtcr r0                 /* Restore CR from R0.  No More Branches!  */
 
-       /* We should really use VRSAVE to figure out which vector regs
+       /* ??? We should really use VRSAVE to figure out which vector regs
           we actually need to save and restore.  Some other time :-/  */
 
        li r11,-192

Reply via email to