aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.3
diff options
context:
space:
mode:
authorAndrew Hsieh <andrewhsieh@google.com>2012-11-28 15:51:52 +0800
committerAndrew Hsieh <andrewhsieh@google.com>2012-11-28 15:51:52 +0800
commitab71b16e5ca5d6bfb9f298a5bf01db312047512d (patch)
tree9fb00d6c1e7487e9947cacfb29e7b30028307d0b /gcc-4.4.3
parent954a4ce00a0a2a93c783c30141e9703cca2442f6 (diff)
downloadtoolchain_gcc-ab71b16e5ca5d6bfb9f298a5bf01db312047512d.tar.gz
toolchain_gcc-ab71b16e5ca5d6bfb9f298a5bf01db312047512d.tar.bz2
toolchain_gcc-ab71b16e5ca5d6bfb9f298a5bf01db312047512d.zip
Fix GCC 4.4.3 ARM ICE at emit-rtl.c:1954
Backport r167430 to fix issue http://code.google.com/p/android/issues/detail?id=22336 r167430 | froydnj | 2010-12-03 23:16:34 +0800 (Fri, 03 Dec 2010) | 10 lines 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. Change-Id: Id78164ff2c29b042998a79b26556bb44ff8b8dec
Diffstat (limited to 'gcc-4.4.3')
-rw-r--r--gcc-4.4.3/gcc/config/arm/arm.c32
-rw-r--r--gcc-4.4.3/gcc/testsuite/gcc.target/arm/neon-offset-1.c11
2 files changed, 39 insertions, 4 deletions
diff --git a/gcc-4.4.3/gcc/config/arm/arm.c b/gcc-4.4.3/gcc/config/arm/arm.c
index 0904cbda9..1be200980 100644
--- a/gcc-4.4.3/gcc/config/arm/arm.c
+++ b/gcc-4.4.3/gcc/config/arm/arm.c
@@ -5133,13 +5133,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
@@ -5250,13 +5262,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;
diff --git a/gcc-4.4.3/gcc/testsuite/gcc.target/arm/neon-offset-1.c b/gcc-4.4.3/gcc/testsuite/gcc.target/arm/neon-offset-1.c
new file mode 100644
index 000000000..91dde6a20
--- /dev/null
+++ b/gcc-4.4.3/gcc/testsuite/gcc.target/arm/neon-offset-1.c
@@ -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);
+}