From: froydnj Date: Fri, 3 Dec 2010 15:16:34 +0000 (+0000) Subject: gcc/ X-Git-Tag: upstream/4.9.2~24401 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=544ccf4a04e849c3407fcc9f8b080e776b9b3cb3;p=platform%2Fupstream%2Flinaro-gcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167430 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1baf78a..5fb26ae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2010-12-03 Nathan Froyd + + * 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 * common.opt (N, Q, Qn, Qy, Z, n, r, s, t): New options. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 3871460..88c43e3 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d5bd085..c75ed75 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-12-03 Nathan Froyd + + * gcc.target/arm/neon-offset-1.c: New test. + 2010-12-03 Alexander Monakov 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 index 0000000..91dde6a --- /dev/null +++ b/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 + +void neon_internal_error(int32x4_t *dst, char *src) +{ + *dst = *(int32x4_t *)(src+1008); +}