aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2016-08-01 10:20:03 +0000
committerKyrylo Tkachov <kyrylo.tkachov@arm.com>2016-08-01 10:20:03 +0000
commit87cf1a8b214d0101b96bf600199d34c7a7411c10 (patch)
tree09d809978a648dcb7c75f1a5158ac34c046ee0d7
parentf23195195a8d9d3e2a5a392097947d2c9ff68a54 (diff)
[AArch64] Allow multiple-of-8 immediate offsets for TImode LDP/STP
* config/aarch64/aarch64.c (aarch64_classify_address): Use DImode when performing aarch64_offset_7bit_signed_scaled_p check for TImode LDP/STP addresses. * gcc.target/aarch64/ldp_stp_unaligned_1.c: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@238938 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/aarch64/aarch64.c6
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_1.c20
4 files changed, 34 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 43c1be9d636..14eb86bc281 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-08-01 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_classify_address): Use DImode when
+ performing aarch64_offset_7bit_signed_scaled_p check for TImode LDP/STP
+ addresses.
+
2016-08-01 Virendra Pathak <virendra.pathak@broadcom.com>
* config/aarch64/aarch64.c (vulcan_tunings): Update
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 61f5f58844e..f2ed83c400f 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3994,9 +3994,11 @@ aarch64_classify_address (struct aarch64_address_info *info,
X,X: 7-bit signed scaled offset
Q: 9-bit signed offset
We conservatively require an offset representable in either mode.
- */
+ When performing the check for pairs of X registers i.e. LDP/STP
+ pass down DImode since that is the natural size of the LDP/STP
+ instruction memory accesses. */
if (mode == TImode || mode == TFmode)
- return (aarch64_offset_7bit_signed_scaled_p (mode, offset)
+ return (aarch64_offset_7bit_signed_scaled_p (DImode, offset)
&& offset_9bit_signed_unscaled_p (mode, offset));
/* A 7bit offset check because OImode will emit a ldp/stp
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c16b2698624..fa3e0575152 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2016-08-01 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/ldp_stp_unaligned_1.c: New test.
+
2016-08-01 Jan Beulich <jbeulich@suse.com>
* gcc.dg/vshift-6.c, gcc.dg/vshift-7.c: New.
diff --git a/gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_1.c b/gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_1.c
new file mode 100644
index 00000000000..a70f92100fb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_1.c
@@ -0,0 +1,20 @@
+/* { dg-options "-O2" } */
+
+/* Check that we can use a REG + IMM addressing mode when moving an unaligned
+ TImode value to and from memory. */
+
+struct foo
+{
+ long long b;
+ __int128 a;
+} __attribute__ ((packed));
+
+void
+bar (struct foo *p, struct foo *q)
+{
+ p->a = q->a;
+}
+
+/* { dg-final { scan-assembler-not "add\tx\[0-9\]+, x\[0-9\]+" } } */
+/* { dg-final { scan-assembler-times "ldp\tx\[0-9\]+, x\[0-9\], .*8" 1 } } */
+/* { dg-final { scan-assembler-times "stp\tx\[0-9\]+, x\[0-9\], .*8" 1 } } */