Author: pfg
Date: Tue Nov 26 14:52:29 2013
New Revision: 258651
URL: http://svnweb.freebsd.org/changeset/base/258651

Log:
  gcc: Altivec register adjustments from Apple.
  
  Obtained from:        gcc pre-4.3 (rev. 124763; GPLv2)
  MFC after:    3 weeks

Modified:
  head/contrib/gcc/ChangeLog.gcc43
  head/contrib/gcc/config/rs6000/rs6000.c

Modified: head/contrib/gcc/ChangeLog.gcc43
==============================================================================
--- head/contrib/gcc/ChangeLog.gcc43    Tue Nov 26 14:50:39 2013        
(r258650)
+++ head/contrib/gcc/ChangeLog.gcc43    Tue Nov 26 14:52:29 2013        
(r258651)
@@ -31,6 +31,12 @@
        regs_invalidated_by_call, rather than just checking the
        membership of REGNO (REG).
 
+2007-05-16  Eric Christopher  <echri...@apple.com> (r124763)
+
+       * config/rs6000/rs6000.c (rs6000_emit_prologue): Move altivec register
+        saving after stack push. Set sp_offset whenever we push.
+        (rs6000_emit_epilogue): Move altivec register restore before stack 
push.
+
 2007-05-03  Ian Lance Taylor  <i...@google.com> (r124381)
 
        * config/rs6000/rs6000.c (rs6000_override_options): Don't set

Modified: head/contrib/gcc/config/rs6000/rs6000.c
==============================================================================
--- head/contrib/gcc/config/rs6000/rs6000.c     Tue Nov 26 14:50:39 2013        
(r258650)
+++ head/contrib/gcc/config/rs6000/rs6000.c     Tue Nov 26 14:52:29 2013        
(r258651)
@@ -14466,77 +14466,6 @@ rs6000_emit_prologue (void)
       sp_offset = info->total_size;
     }
 
-  /* Save AltiVec registers if needed.  */
-  if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
-    {
-      int i;
-
-      /* There should be a non inline version of this, for when we
-        are saving lots of vector registers.  */
-      for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
-       if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
-         {
-           rtx areg, savereg, mem;
-           int offset;
-
-           offset = info->altivec_save_offset + sp_offset
-             + 16 * (i - info->first_altivec_reg_save);
-
-           savereg = gen_rtx_REG (V4SImode, i);
-
-           areg = gen_rtx_REG (Pmode, 0);
-           emit_move_insn (areg, GEN_INT (offset));
-
-           /* AltiVec addressing mode is [reg+reg].  */
-           mem = gen_frame_mem (V4SImode,
-                                gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
-
-           insn = emit_move_insn (mem, savereg);
-
-           rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
-                                 areg, GEN_INT (offset));
-         }
-    }
-
-  /* VRSAVE is a bit vector representing which AltiVec registers
-     are used.  The OS uses this to determine which vector
-     registers to save on a context switch.  We need to save
-     VRSAVE on the stack frame, add whatever AltiVec registers we
-     used in this function, and do the corresponding magic in the
-     epilogue.  */
-
-  if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
-      && info->vrsave_mask != 0)
-    {
-      rtx reg, mem, vrsave;
-      int offset;
-
-      /* Get VRSAVE onto a GPR.  Note that ABI_V4 might be using r12
-        as frame_reg_rtx and r11 as the static chain pointer for
-        nested functions.  */
-      reg = gen_rtx_REG (SImode, 0);
-      vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
-      if (TARGET_MACHO)
-       emit_insn (gen_get_vrsave_internal (reg));
-      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);
-       }
-
-      /* Include the registers in the mask.  */
-      emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
-
-      insn = emit_insn (generate_set_vrsave (reg, info, 0));
-    }
-
   /* If we use the link register, get it into r0.  */
   if (!WORLD_SAVE_P (info) && info->lr_save_p)
     {
@@ -14774,7 +14703,10 @@ rs6000_emit_prologue (void)
      for which it was done previously.  */
   if (!WORLD_SAVE_P (info) && info->push_p
       && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
-    rs6000_emit_allocate_stack (info->total_size, FALSE);
+    {
+      rs6000_emit_allocate_stack (info->total_size, FALSE);
+      sp_offset = info->total_size;
+    }
 
   /* Set frame pointer, if needed.  */
   if (frame_pointer_needed)
@@ -14784,6 +14716,78 @@ rs6000_emit_prologue (void)
       RTX_FRAME_RELATED_P (insn) = 1;
     }
 
+  /* Save AltiVec registers if needed.  Save here because the red zone does
+     not include AltiVec registers.  */
+  if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
+    {
+      int i;
+
+      /* There should be a non inline version of this, for when we
+         are saving lots of vector registers.  */
+      for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
+        if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
+          {
+            rtx areg, savereg, mem;
+            int offset;
+
+            offset = info->altivec_save_offset + sp_offset
+              + 16 * (i - info->first_altivec_reg_save);
+
+            savereg = gen_rtx_REG (V4SImode, i);
+
+            areg = gen_rtx_REG (Pmode, 0);
+            emit_move_insn (areg, GEN_INT (offset));
+
+            /* AltiVec addressing mode is [reg+reg].  */
+            mem = gen_frame_mem (V4SImode,
+                                 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
+
+            insn = emit_move_insn (mem, savereg);
+
+            rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+                                  areg, GEN_INT (offset));
+          }
+    }
+
+  /* VRSAVE is a bit vector representing which AltiVec registers
+     are used.  The OS uses this to determine which vector
+     registers to save on a context switch.  We need to save
+     VRSAVE on the stack frame, add whatever AltiVec registers we
+     used in this function, and do the corresponding magic in the
+     epilogue.  */
+
+  if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
+      && info->vrsave_mask != 0)
+    {
+      rtx reg, mem, vrsave;
+      int offset;
+
+      /* Get VRSAVE onto a GPR.  Note that ABI_V4 might be using r12
+         as frame_reg_rtx and r11 as the static chain pointer for
+         nested functions.  */
+      reg = gen_rtx_REG (SImode, 0);
+      vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
+      if (TARGET_MACHO)
+        emit_insn (gen_get_vrsave_internal (reg));
+      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);
+        }
+
+      /* Include the registers in the mask.  */
+      emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
+
+      insn = emit_insn (generate_set_vrsave (reg, info, 0));
+    }
+
   /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up.  */
   if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
       || (DEFAULT_ABI == ABI_V4
@@ -15041,33 +15045,10 @@ rs6000_emit_epilogue (int sibcall)
       return;
     }
 
-  /* If we have a frame pointer, a call to alloca,  or a large stack
-     frame, restore the old stack pointer using the backchain.  Otherwise,
-     we know what size to update it with.  */
-  if (use_backchain_to_restore_sp)
-    {
-      /* Under V.4, don't reset the stack pointer until after we're done
-        loading the saved registers.  */
-      if (DEFAULT_ABI == ABI_V4)
-       frame_reg_rtx = gen_rtx_REG (Pmode, 11);
-
-      emit_move_insn (frame_reg_rtx,
-                     gen_rtx_MEM (Pmode, sp_reg_rtx));
-    }
-  else if (info->push_p)
-    {
-      if (DEFAULT_ABI == ABI_V4
-         || current_function_calls_eh_return)
-       sp_offset = info->total_size;
-      else
-       {
-         emit_insn (TARGET_32BIT
-                    ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
-                                  GEN_INT (info->total_size))
-                    : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
-                                  GEN_INT (info->total_size)));
-       }
-    }
+  /* Set sp_offset based on the stack push from the prologue.  */
+  if ((DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return)
+      && info->total_size < 32767)
+    sp_offset = info->total_size;
 
   /* Restore AltiVec registers if needed.  */
   if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
@@ -15108,6 +15089,36 @@ rs6000_emit_epilogue (int sibcall)
       emit_insn (generate_set_vrsave (reg, info, 1));
     }
 
+  sp_offset = 0;
+
+  /* If we have a frame pointer, a call to alloca,  or a large stack
+     frame, restore the old stack pointer using the backchain.  Otherwise,
+     we know what size to update it with.  */
+  if (use_backchain_to_restore_sp)
+    {
+      /* Under V.4, don't reset the stack pointer until after we're done
+        loading the saved registers.  */
+      if (DEFAULT_ABI == ABI_V4)
+       frame_reg_rtx = gen_rtx_REG (Pmode, 11);
+
+      emit_move_insn (frame_reg_rtx,
+                     gen_rtx_MEM (Pmode, sp_reg_rtx));
+    }
+  else if (info->push_p)
+    {
+      if (DEFAULT_ABI == ABI_V4
+         || current_function_calls_eh_return)
+       sp_offset = info->total_size;
+      else
+       {
+         emit_insn (TARGET_32BIT
+                    ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
+                                  GEN_INT (info->total_size))
+                    : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
+                                  GEN_INT (info->total_size)));
+       }
+    }
+
   /* Get the old lr if we saved it.  */
   if (info->lr_save_p)
     {
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to