]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
arm.c (arm_legitimate_index_p): Split VALID_NEON_QREG_MODE and VALID_NEON_DREG_MODE...
authorNathan Froyd <froydnj@codesourcery.com>
Fri, 3 Dec 2010 15:16:34 +0000 (15:16 +0000)
committerNathan Froyd <froydnj@gcc.gnu.org>
Fri, 3 Dec 2010 15:16:34 +0000 (15:16 +0000)
gcc/
* config/arm/arm.c (arm_legitimate_index_p): Split
VALID_NEON_QREG_MODE and VALID_NEON_DREG_MODE cases.  Permit
slightly larger constants in the latter case.
(thumb2_legitimate_index_p): Likewise.

gcc/testsuite/
* gcc.target/arm/neon-offset-1.c: New test.

From-SVN: r167430

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/neon-offset-1.c [new file with mode: 0644]

index 1baf78a279a3f1f7e896cf63182bc4148a221761..5fb26aedef8c8b482347eb533bc75dd6d593b127 100644 (file)
@@ -1,3 +1,10 @@
+2010-12-03  Nathan Froyd  <froydnj@codesourcery.com>
+
+       * config/arm/arm.c (arm_legitimate_index_p): Split
+       VALID_NEON_QREG_MODE and VALID_NEON_DREG_MODE cases.  Permit
+       slightly larger constants in the latter case.
+       (thumb2_legitimate_index_p): Likewise.
+
 2010-12-03  Joseph Myers  <joseph@codesourcery.com>
 
        * common.opt (N, Q, Qn, Qy, Z, n, r, s, t): New options.
index 38714609cabf5f3f5d76f8f359d38dd1bfae8956..88c43e3c3a9cc59992d4125556a00711d38ae91f 100644 (file)
@@ -5649,13 +5649,25 @@ arm_legitimate_index_p (enum machine_mode mode, rtx index, RTX_CODE outer,
            && INTVAL (index) > -1024
            && (INTVAL (index) & 3) == 0);
 
-  if (TARGET_NEON
-      && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode)))
+  /* For quad modes, we restrict the constant offset to be slightly less
+     than what the instruction format permits.  We do this because for
+     quad mode moves, we will actually decompose them into two separate
+     double-mode reads or writes.  INDEX must therefore be a valid
+     (double-mode) offset and so should INDEX+8.  */
+  if (TARGET_NEON && VALID_NEON_QREG_MODE (mode))
     return (code == CONST_INT
            && INTVAL (index) < 1016
            && INTVAL (index) > -1024
            && (INTVAL (index) & 3) == 0);
 
+  /* We have no such constraint on double mode offsets, so we permit the
+     full range of the instruction format.  */
+  if (TARGET_NEON && VALID_NEON_DREG_MODE (mode))
+    return (code == CONST_INT
+           && INTVAL (index) < 1024
+           && INTVAL (index) > -1024
+           && (INTVAL (index) & 3) == 0);
+
   if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
     return (code == CONST_INT
            && INTVAL (index) < 1024
@@ -5769,13 +5781,25 @@ thumb2_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p)
                && (INTVAL (index) & 3) == 0);
     }
 
-  if (TARGET_NEON
-      && (VALID_NEON_DREG_MODE (mode) || VALID_NEON_QREG_MODE (mode)))
+  /* For quad modes, we restrict the constant offset to be slightly less
+     than what the instruction format permits.  We do this because for
+     quad mode moves, we will actually decompose them into two separate
+     double-mode reads or writes.  INDEX must therefore be a valid
+     (double-mode) offset and so should INDEX+8.  */
+  if (TARGET_NEON && VALID_NEON_QREG_MODE (mode))
     return (code == CONST_INT
            && INTVAL (index) < 1016
            && INTVAL (index) > -1024
            && (INTVAL (index) & 3) == 0);
 
+  /* We have no such constraint on double mode offsets, so we permit the
+     full range of the instruction format.  */
+  if (TARGET_NEON && VALID_NEON_DREG_MODE (mode))
+    return (code == CONST_INT
+           && INTVAL (index) < 1024
+           && INTVAL (index) > -1024
+           && (INTVAL (index) & 3) == 0);
+
   if (arm_address_register_rtx_p (index, strict_p)
       && (GET_MODE_SIZE (mode) <= 4))
     return 1;
index d5bd085cb5037cfe8f4bb103124c9832fe96a2ef..c75ed75e177acaaf2c9db98976f079bc573cccbc 100644 (file)
@@ -1,3 +1,7 @@
+2010-12-03  Nathan Froyd  <froydnj@codesourcery.com>
+
+       * gcc.target/arm/neon-offset-1.c: New test.
+
 2010-12-03  Alexander Monakov  <amonakov@ispras.ru>
 
        PR rtl-optimization/45354
diff --git a/gcc/testsuite/gcc.target/arm/neon-offset-1.c b/gcc/testsuite/gcc.target/arm/neon-offset-1.c
new file mode 100644 (file)
index 0000000..91dde6a
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-O1" } */
+/* { dg-add-options arm_neon } */
+
+#include <arm_neon.h>
+
+void neon_internal_error(int32x4_t *dst, char *src)
+{
+  *dst = *(int32x4_t *)(src+1008);
+}