]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rtl.h (simplify_subreg_regno): Declare.
authorRichard Sandiford <rdsandiford@googlemail.com>
Thu, 28 Aug 2008 20:02:54 +0000 (20:02 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 28 Aug 2008 20:02:54 +0000 (20:02 +0000)
gcc/
* rtl.h (simplify_subreg_regno): Declare.
* rtlanal.c (simplify_subreg_regno): New function, split out from...
* simplify-rtx.c (simplify_subreg): ...here.
* reload.c (find_reloads): Use simplify_subreg_regno instead of
subreg_offset_representable_p.

From-SVN: r139736

gcc/ChangeLog
gcc/reload.c
gcc/rtl.h
gcc/rtlanal.c
gcc/simplify-rtx.c

index 2fe77890a0ea71433c70c2e0d51602eef6ddc773..22f639bd8be9faa423646c6e39842bdb2f527e9a 100644 (file)
@@ -1,3 +1,11 @@
+2008-08-28  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * rtl.h (simplify_subreg_regno): Declare.
+       * rtlanal.c (simplify_subreg_regno): New function, split out from...
+       * simplify-rtx.c (simplify_subreg): ...here.
+       * reload.c (find_reloads): Use simplify_subreg_regno instead of
+       subreg_offset_representable_p.
+
 2008-08-28  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR c/30949
index 816370079954747df6e30655fda3db0785c64cd7..e353c50acdb19f7473c59c64e690c65eb56007c3 100644 (file)
@@ -2999,12 +2999,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
              if (REG_P (SUBREG_REG (operand))
                  && REGNO (SUBREG_REG (operand)) < FIRST_PSEUDO_REGISTER)
                {
-                 if (!subreg_offset_representable_p
-                       (REGNO (SUBREG_REG (operand)),
-                        GET_MODE (SUBREG_REG (operand)),
-                        SUBREG_BYTE (operand),
-                        GET_MODE (operand)))
-                    force_reload = 1;
+                 if (simplify_subreg_regno (REGNO (SUBREG_REG (operand)),
+                                            GET_MODE (SUBREG_REG (operand)),
+                                            SUBREG_BYTE (operand),
+                                            GET_MODE (operand)) < 0)
+                   force_reload = 1;
                  offset += subreg_regno_offset (REGNO (SUBREG_REG (operand)),
                                                 GET_MODE (SUBREG_REG (operand)),
                                                 SUBREG_BYTE (operand),
index 42fc2ad6b6474b6534e292997789798183460f86..9e7d40ad6e5661874f0db75c819d2d25af36f1ae 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1084,6 +1084,8 @@ extern unsigned int subreg_regno_offset   (unsigned int, enum machine_mode,
 extern bool subreg_offset_representable_p (unsigned int, enum machine_mode,
                                           unsigned int, enum machine_mode);
 extern unsigned int subreg_regno (const_rtx);
+extern int simplify_subreg_regno (unsigned int, enum machine_mode,
+                                 unsigned int, enum machine_mode);
 extern unsigned int subreg_nregs (const_rtx);
 extern unsigned int subreg_nregs_with_regno (unsigned int, const_rtx);
 extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, enum machine_mode);
index 00a63cd9b960ac0d7bcbea1c501b060fa2ecff44..9c5a1e53c7f553adc266e458987d84da3d235c14 100644 (file)
@@ -3244,6 +3244,64 @@ subreg_offset_representable_p (unsigned int xregno, enum machine_mode xmode,
   return info.representable_p;
 }
 
+/* Return the number of a YMODE register to which
+
+       (subreg:YMODE (reg:XMODE XREGNO) OFFSET)
+
+   can be simplified.  Return -1 if the subreg can't be simplified.
+
+   XREGNO is a hard register number.  */
+
+int
+simplify_subreg_regno (unsigned int xregno, enum machine_mode xmode,
+                      unsigned int offset, enum machine_mode ymode)
+{
+  struct subreg_info info;
+  unsigned int yregno;
+
+#ifdef CANNOT_CHANGE_MODE_CLASS
+  /* Give the backend a chance to disallow the mode change.  */
+  if (GET_MODE_CLASS (xmode) != MODE_COMPLEX_INT
+      && GET_MODE_CLASS (xmode) != MODE_COMPLEX_FLOAT
+      && REG_CANNOT_CHANGE_MODE_P (xregno, xmode, ymode))
+    return -1;
+#endif
+
+  /* We shouldn't simplify stack-related registers.  */
+  if ((!reload_completed || frame_pointer_needed)
+      && (xregno == FRAME_POINTER_REGNUM
+         || xregno == HARD_FRAME_POINTER_REGNUM))
+    return -1;
+
+  if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+      && xregno == ARG_POINTER_REGNUM)
+    return -1;
+
+  if (xregno == STACK_POINTER_REGNUM)
+    return -1;
+
+  /* Try to get the register offset.  */
+  subreg_get_info (xregno, xmode, offset, ymode, &info);
+  if (!info.representable_p)
+    return -1;
+
+  /* Make sure that the offsetted register value is in range.  */
+  yregno = xregno + info.offset;
+  if (!HARD_REGISTER_NUM_P (yregno))
+    return -1;
+
+  /* See whether (reg:YMODE YREGNO) is valid.
+
+     ??? We allow invalid registers if (reg:XMODE XREGNO) is also invalid.
+     This is a kludge to work around how float/complex arguments are passed
+     on 32-bit SPARC and should be fixed.  */
+  if (!HARD_REGNO_MODE_OK (yregno, ymode)
+      && HARD_REGNO_MODE_OK (xregno, xmode))
+    return -1;
+
+  return (int) yregno;
+}
+
 /* Return the final regno that a subreg expression refers to.  */
 unsigned int
 subreg_regno (const_rtx x)
index 6fd77ff1543be2e63243b773b13fd0a58e9be8cd..606a850622ca9f0278e77dec752e73f19384f75d 100644 (file)
@@ -5069,35 +5069,13 @@ simplify_subreg (enum machine_mode outermode, rtx op,
      suppress this simplification.  If the hard register is the stack,
      frame, or argument pointer, leave this as a SUBREG.  */
 
-  if (REG_P (op)
-      && REGNO (op) < FIRST_PSEUDO_REGISTER
-#ifdef CANNOT_CHANGE_MODE_CLASS
-      && ! (REG_CANNOT_CHANGE_MODE_P (REGNO (op), innermode, outermode)
-           && GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
-           && GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT)
-#endif
-      && ((reload_completed && !frame_pointer_needed)
-         || (REGNO (op) != FRAME_POINTER_REGNUM
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
-             && REGNO (op) != HARD_FRAME_POINTER_REGNUM
-#endif
-            ))
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-      && REGNO (op) != ARG_POINTER_REGNUM
-#endif
-      && REGNO (op) != STACK_POINTER_REGNUM
-      && subreg_offset_representable_p (REGNO (op), innermode,
-                                       byte, outermode))
+  if (REG_P (op) && HARD_REGISTER_P (op))
     {
-      unsigned int regno = REGNO (op);
-      unsigned int final_regno
-       = regno + subreg_regno_offset (regno, innermode, byte, outermode);
-
-      /* ??? We do allow it if the current REG is not valid for
-        its mode.  This is a kludge to work around how float/complex
-        arguments are passed on 32-bit SPARC and should be fixed.  */
-      if (HARD_REGNO_MODE_OK (final_regno, outermode)
-         || ! HARD_REGNO_MODE_OK (regno, innermode))
+      unsigned int regno, final_regno;
+
+      regno = REGNO (op);
+      final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
+      if (HARD_REGISTER_NUM_P (final_regno))
        {
          rtx x;
          int final_offset = byte;