diff options
Diffstat (limited to 'gcc-4.4.3')
-rw-r--r-- | gcc-4.4.3/gcc/config/arm/arm.c | 32 | ||||
-rw-r--r-- | gcc-4.4.3/gcc/testsuite/gcc.target/arm/neon-offset-1.c | 11 |
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 4bad1ca72..054383ca0 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); +} |