]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000.c (rs6000_emit_prologue): Move altivec register saving after stack push.
authorEric Christopher <echristo@gcc.gnu.org>
Wed, 16 May 2007 08:30:10 +0000 (08:30 +0000)
committerEric Christopher <echristo@gcc.gnu.org>
Wed, 16 May 2007 08:30:10 +0000 (08:30 +0000)
2007-05-16  Eric Christopher  <echristo@apple.com>

* 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.

From-SVN: r124763

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index 847d10dd82f36683482c3d25ce6bb9c66f07e24b..dfa19ac6a6d9dce530c2d632193616bf3301e629 100644 (file)
@@ -1,3 +1,9 @@
+2007-05-16  Eric Christopher  <echristo@apple.com>
+
+       * 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-16  Richard Sandiford  <richard@codesourcery.com>
 
        * configure.ac: Allow sysroots to be relocated under $prefix as
        * tree-flow.h (strict_aliasing_warning_backend): Declare.
        * tree-ssa-alias-warnings.c: New file.
        * tree-ssa-alias.c (compute_may_aliases): Add call to
-       strict_aliasing_warning_backend. 
+       strict_aliasing_warning_backend.
 
 2007-05-11  Zdenek Dvorak  <dvorakz@suse.cz>
 
        emit_call_insn.
 
 2007-05-09  Bob Wilson  <bob.wilson@acm.org>
-       
+
        * config/xtensa/xtensa.c (xtensa_output_literal): Don't use #if.
-       
+
 2007-05-09  Bob Wilson  <bob.wilson@acm.org>
 
        * config/xtensa/xtensa.c (xtensa_output_literal): Mask out high bits
        bfin_expand_epilogue accordingly.
        (sibcall_epilogue): Likewise.
        (eh_return_internal): Likewise.
-               
+
        * config/bfin/bfin-protos.h (enum bfin_cpu): Add
        BFIN_CPU_BF534, BFIN_CPU_BF536 and BFIN_CPU_BF561.
        * config/bfin/bfin.c (bfin_handle_option): Handle
        PR target/31854
        * config/i386/i386.c (ix86_function_regparm): Process local
        functions only when TREE_CODE (decl) equals FUNCTION_DECL.
-       
+
 2007-05-07  Mike Stump  <mrs@apple.com>
 
        * doc/invoke.texi (Warning Options): Document that -Wempty-body
        (function_vector_handler): New
        (current_function_special_page_vector): New
        (m32c_special_page_vector_p): New.
-       * config/m32c/m32c-protos.h (m32c_special_page_vector_p): 
+       * config/m32c/m32c-protos.h (m32c_special_page_vector_p):
        Prototype.
-       * config/m32c/jump.md: Added instruction JSRS for functions 
+       * config/m32c/jump.md: Added instruction JSRS for functions
        with attribute "function_vector".
-       * doc/extend.texi (function_vector): Added description 
+       * doc/extend.texi (function_vector): Added description
        for M16C, M32C targets.
 
 2007-05-07  DJ Delorie  <dj@redhat.com>
 2007-05-05  Aurelien Jarno  <aurelien@aurel32.net>
 
        * config/pa/pa.md: Split tgd_load, tld_load and tie_load
-       into pic and non-pic versions. Mark r19 as used for 
-       tgd_load_pic, tld_load_pic and tie_load_pic. Mark r27 as used 
+       into pic and non-pic versions. Mark r19 as used for
+       tgd_load_pic, tld_load_pic and tie_load_pic. Mark r27 as used
        for tgd_load, tld_load and tie_load .
        * config/pa/pa.c (legitimize_tls_address): Emit pic or non-pic
-       version of tgd_load, tld_load and tie_load depending on the 
+       version of tgd_load, tld_load and tie_load depending on the
        value of flag_pic.
 
 2007-05-04  Ulrich Drepper  <drepper@redhat.com>
        ("fix_trunc<DSF:mode><GPR:mode>2"): Expander added.
 
 2007-05-04  Bob Wilson  <bob.wilson@acm.org>
-       
+
        * config/xtensa/xtensa.md (adddi3, adddi_carry): Delete.
        (subdi3, subdi_carry): Delete.
-       
+
 2007-05-04  Jan Hubicka  <jh@suse.cz>
            Richard Guenther  <rguenther@suse.de>
 
        with changed signature and 'debug_rgn_dependencies ()'.
        (debug_rgn_dependencies): New static function.
        (init_ready_list): Use it.
-       
+
        * sched-int.h (debug_dependencies): Declare.
 
 2007-05-04  Andreas Krebbel  <krebbel1@de.ibm.com>
        PR tree-optimization/31699
        * tree-vect-analyze.c (vect_update_misalignment_for_peel): Remove wrong
        code.
-       (vect_enhance_data_refs_alignment): Compute peel amount using 
-       TYPE_VECTOR_SUBPARTS instead of vf.     
+       (vect_enhance_data_refs_alignment): Compute peel amount using
+       TYPE_VECTOR_SUBPARTS instead of vf.
        * tree-vect-transform.c (vect_gen_niters_for_prolog_loop): Likewise.
 
 2007-05-02  Brooks Moses  <brooks.moses@codesourcery.com>
index 61564a270b4ab3823ce91e410b53f4cfd720e046..6447138773807d30891ccca80ce34db42271a9ad 100644 (file)
@@ -14812,77 +14812,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)
     {
@@ -15120,7 +15049,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)
@@ -15130,6 +15062,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
@@ -15387,33 +15391,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)
@@ -15454,6 +15435,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)
     {