gcc/
authorfroydnj <froydnj@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 3 Dec 2010 15:16:34 +0000 (15:16 +0000)
committerfroydnj <froydnj@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 3 Dec 2010 15:16:34 +0000 (15:16 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167430 138bc75d-0d04-0410-961f-82ee72b054a4

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 1baf78a..5fb26ae 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 3871460..88c43e3 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 d5bd085..c75ed75 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);
+}