diff options
author | Andrew Hsieh <andrewhsieh@google.com> | 2012-11-28 15:51:52 +0800 |
---|---|---|
committer | Andrew Hsieh <andrewhsieh@google.com> | 2012-11-28 15:51:52 +0800 |
commit | ab71b16e5ca5d6bfb9f298a5bf01db312047512d (patch) | |
tree | 9fb00d6c1e7487e9947cacfb29e7b30028307d0b /gcc-4.4.3/gcc/config | |
parent | 954a4ce00a0a2a93c783c30141e9703cca2442f6 (diff) | |
download | toolchain_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/gcc/config')
-rw-r--r-- | gcc-4.4.3/gcc/config/arm/arm.c | 32 |
1 files changed, 28 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; |