[RS6000] Don't restore fixed regs
authorAlan Modra <amodra@gmail.com>
Wed, 16 Aug 2017 01:06:35 +0000 (10:36 +0930)
committerAlan Modra <amodra@gcc.gnu.org>
Wed, 16 Aug 2017 01:06:35 +0000 (10:36 +0930)
* config/rs6000/rs6000.c (rs6000_savres_strategy): Don't restore
fixed regs.

From-SVN: r251114

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

index 14fc3dbe3e0c67d0fe586f5b8aceb84c6d753575..4e6720faf9d6f80e063e2dd14828d729fc9b61c3 100644 (file)
@@ -1,3 +1,8 @@
+2017-08-16  Alan Modra  <amodra@gmail.com>
+
+       * config/rs6000/rs6000.c (rs6000_savres_strategy): Don't restore
+       fixed regs.
+
 2017-08-15  Joseph Myers  <joseph@codesourcery.com>
 
        PR target/78460
index 1360c15eb693059649b41bd701f02d664205c50b..5510306efdf2a33ec2964c06d4fe674c170c3b17 100644 (file)
@@ -24406,36 +24406,47 @@ rs6000_savres_strategy (rs6000_stack_t *info,
                 | SAVE_INLINE_GPRS
                 | SAVE_INLINE_VRS);
 
+  /* Don't ever restore fixed regs.  That means we can't use the
+     out-of-line register restore functions if a fixed reg is in the
+     range of regs restored.   */
+  if (!(strategy & REST_INLINE_FPRS))
+    for (int i = info->first_fp_reg_save; i < 64; i++)
+      if (fixed_regs[i])
+       {
+         strategy |= REST_INLINE_FPRS;
+         break;
+       }
+
   /* We can only use the out-of-line routines to restore fprs if we've
      saved all the registers from first_fp_reg_save in the prologue.
      Otherwise, we risk loading garbage.  Of course, if we have saved
      out-of-line then we know we haven't skipped any fprs.  */
   if ((strategy & SAVE_INLINE_FPRS)
       && !(strategy & REST_INLINE_FPRS))
-    {
-      int i;
-
-      for (i = info->first_fp_reg_save; i < 64; i++)
-       if (fixed_regs[i] || !save_reg_p (i))
-         {
-           strategy |= REST_INLINE_FPRS;
-           break;
-         }
-    }
+    for (int i = info->first_fp_reg_save; i < 64; i++)
+      if (!save_reg_p (i))
+       {
+         strategy |= REST_INLINE_FPRS;
+         break;
+       }
 
   /* Similarly, for altivec regs.  */
+  if (!(strategy & REST_INLINE_VRS))
+    for (int i = info->first_altivec_reg_save; i < LAST_ALTIVEC_REGNO + 1; i++)
+      if (fixed_regs[i])
+       {
+         strategy |= REST_INLINE_VRS;
+         break;
+       }
+
   if ((strategy & SAVE_INLINE_VRS)
       && !(strategy & REST_INLINE_VRS))
-    {
-      int i;
-
-      for (i = info->first_altivec_reg_save; i < LAST_ALTIVEC_REGNO + 1; i++)
-       if (fixed_regs[i] || !save_reg_p (i))
-         {
-           strategy |= REST_INLINE_VRS;
-           break;
-         }
-    }
+    for (int i = info->first_altivec_reg_save; i < LAST_ALTIVEC_REGNO + 1; i++)
+      if (!save_reg_p (i))
+       {
+         strategy |= REST_INLINE_VRS;
+         break;
+       }
 
   /* info->lr_save_p isn't yet set if the only reason lr needs to be
      saved is an out-of-line save or restore.  Set up the value for
@@ -24490,6 +24501,16 @@ rs6000_savres_strategy (rs6000_stack_t *info,
          }
     }
 
+  /* Don't ever restore fixed regs.  */
+  if ((strategy & (REST_INLINE_GPRS | REST_MULTIPLE)) != REST_INLINE_GPRS)
+    for (int i = info->first_gp_reg_save; i < 32; i++)
+      if (fixed_reg_p (i))
+       {
+         strategy |= REST_INLINE_GPRS;
+         strategy &= ~REST_MULTIPLE;
+         break;
+       }
+
   /* We can only use load multiple or the out-of-line routines to
      restore gprs if we've saved all the registers from
      first_gp_reg_save.  Otherwise, we risk loading garbage.
@@ -24497,17 +24518,13 @@ rs6000_savres_strategy (rs6000_stack_t *info,
      we haven't skipped any gprs.  */
   if ((strategy & (SAVE_INLINE_GPRS | SAVE_MULTIPLE)) == SAVE_INLINE_GPRS
       && (strategy & (REST_INLINE_GPRS | REST_MULTIPLE)) != REST_INLINE_GPRS)
-    {
-      int i;
-
-      for (i = info->first_gp_reg_save; i < 32; i++)
-       if (fixed_reg_p (i) || !save_reg_p (i))
-         {
-           strategy |= REST_INLINE_GPRS;
-           strategy &= ~REST_MULTIPLE;
-           break;
-         }
-    }
+    for (int i = info->first_gp_reg_save; i < 32; i++)
+      if (!save_reg_p (i))
+       {
+         strategy |= REST_INLINE_GPRS;
+         strategy &= ~REST_MULTIPLE;
+         break;
+       }
 
   if (TARGET_ELF && TARGET_64BIT)
     {