From 87cf1a8b214d0101b96bf600199d34c7a7411c10 Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Mon, 1 Aug 2016 10:20:03 +0000 Subject: [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 --- gcc/ChangeLog | 6 ++++++ gcc/config/aarch64/aarch64.c | 6 ++++-- gcc/testsuite/ChangeLog | 4 ++++ .../gcc.target/aarch64/ldp_stp_unaligned_1.c | 20 ++++++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/ldp_stp_unaligned_1.c 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 + + * 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 * 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 + + * gcc.target/aarch64/ldp_stp_unaligned_1.c: New test. + 2016-08-01 Jan Beulich * 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 } } */ -- cgit v1.2.3