aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordardiss <dardiss@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-20 09:45:33 +0000
committerdardiss <dardiss@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-20 09:45:33 +0000
commit1731ea5816a05ba969926868f3ffe733d2d4bdbd (patch)
tree901959ccb3e8165aa8dda975ea4a4cf70526a026
parent376211b1f2a82997794882981cbf4294804a6e05 (diff)
gcc/
* config/mips/mips.c (mips_expand_block_move): Enable inline memcpy expansion when !ISA_HAS_LWL_LWR. (mips_block_move_straight): Update the size of elements copied to account for alignment when !ISA_HAS_LWL_LWR. * config/mips/mips.h (MIPS_MIN_MOVE_MEM_ALIGN): New macro. gcc/testsuite/ * inline-memcpy-1.c: Test for inline expansion of memcpy. * inline-memcpy-2.c: Ditto. * inline-memcpy-3.c: Ditto. * inline-memcpy-4.c: Ditto. * inline-memcpy-5.c: Ditto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227026 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/mips/mips.c25
-rw-r--r--gcc/config/mips/mips.h3
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.target/mips/inline-memcpy-1.c16
-rw-r--r--gcc/testsuite/gcc.target/mips/inline-memcpy-2.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/inline-memcpy-3.c18
-rw-r--r--gcc/testsuite/gcc.target/mips/inline-memcpy-4.c18
-rw-r--r--gcc/testsuite/gcc.target/mips/inline-memcpy-5.c18
9 files changed, 124 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 78a7a7930ba..62459e78af6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2015-08-20 Simon Dardis <simon.dardis@imgtec.com>
+
+ * config/mips/mips.c (mips_expand_block_move): Enable inline memcpy
+ expansion when !ISA_HAS_LWL_LWR.
+ (mips_block_move_straight): Update the size of elements copied to
+ account for alignment when !ISA_HAS_LWL_LWR.
+ * config/mips/mips.h (MIPS_MIN_MOVE_MEM_ALIGN): New macro.
+
2015-08-19 Jiong Wang <jiong.wang@arm.com>
* expr.c (expand_expr_real_2): Check gimple statement during
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 401d73bfeaa..0b4a5faacdb 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -7630,12 +7630,22 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
half-word alignment, it is usually better to move in half words.
For instance, lh/lh/sh/sh is usually better than lwl/lwr/swl/swr
and lw/lw/sw/sw is usually better than ldl/ldr/sdl/sdr.
- Otherwise move word-sized chunks. */
- if (MEM_ALIGN (src) == BITS_PER_WORD / 2
- && MEM_ALIGN (dest) == BITS_PER_WORD / 2)
- bits = BITS_PER_WORD / 2;
+ Otherwise move word-sized chunks.
+
+ For ISA_HAS_LWL_LWR we rely on the lwl/lwr & swl/swr load. Otherwise
+ picking the minimum of alignment or BITS_PER_WORD gets us the
+ desired size for bits. */
+
+ if (!ISA_HAS_LWL_LWR)
+ bits = MIN (BITS_PER_WORD, MIN (MEM_ALIGN (src), MEM_ALIGN (dest)));
else
- bits = BITS_PER_WORD;
+ {
+ if (MEM_ALIGN (src) == BITS_PER_WORD / 2
+ && MEM_ALIGN (dest) == BITS_PER_WORD / 2)
+ bits = BITS_PER_WORD / 2;
+ else
+ bits = BITS_PER_WORD;
+ }
mode = mode_for_size (bits, MODE_INT, 0);
delta = bits / BITS_PER_UNIT;
@@ -7754,8 +7764,9 @@ mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
bool
mips_expand_block_move (rtx dest, rtx src, rtx length)
{
- /* Disable entirely for R6 initially. */
- if (!ISA_HAS_LWL_LWR)
+ if (!ISA_HAS_LWL_LWR
+ && (MEM_ALIGN (src) < MIPS_MIN_MOVE_MEM_ALIGN
+ || MEM_ALIGN (dest) < MIPS_MIN_MOVE_MEM_ALIGN))
return false;
if (CONST_INT_P (length))
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index da1de011fc9..2d44735e6ca 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2981,6 +2981,9 @@ while (0)
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE (POINTER_SIZE == 64 ? "long int" : "int")
+/* The minimum alignment of any expanded block move. */
+#define MIPS_MIN_MOVE_MEM_ALIGN 16
+
/* The maximum number of bytes that can be copied by one iteration of
a movmemsi loop; see mips_block_move_loop. */
#define MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER \
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 076de9ca606..be331444423 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2015-08-20 Simon Dardis <simon.dardis@imgtec.com>
+
+ * gcc.target/mips/inline-memcpy-1.c: Test for inline expansion of memcpy.
+ * gcc.target/mips/inline-memcpy-2.c: Ditto.
+ * gcc.target/mips/inline-memcpy-3.c: Ditto.
+ * gcc.target/mips/inline-memcpy-4.c: Ditto.
+ * gcc.target/mips/inline-memcpy-5.c: Ditto.
+
2015-08-19 Jiong Wang <jiong.wang@arm.com>
* gcc.dg/wide_shift_64_1.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-1.c b/gcc/testsuite/gcc.target/mips/inline-memcpy-1.c
new file mode 100644
index 00000000000..5a254b1eaa9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-1.c
@@ -0,0 +1,16 @@
+/* { dg-options "-fno-common isa_rev>=6" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os" } { "" } } */
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+
+/* Test that memcpy is inline for target hardware
+ without swl, swr. */
+
+#include <string.h>
+
+char c[40] __attribute__ ((aligned(8)));
+
+void
+f1 ()
+{
+ memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32);
+}
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-2.c b/gcc/testsuite/gcc.target/mips/inline-memcpy-2.c
new file mode 100644
index 00000000000..e144e61a800
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-2.c
@@ -0,0 +1,17 @@
+/* { dg-options "-fno-common isa_rev>=6" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os"} { "" } } */
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+/* { dg-final { scan-assembler-times "\tsh\t" 16 } } */
+
+/* Test that inline memcpy is expanded for target hardware without
+ swl, swr when alignment is halfword and sufficent shs are produced. */
+
+#include <string.h>
+
+char c[40] __attribute__ ((aligned(2)));
+
+void
+f1 ()
+{
+ memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32);
+}
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-3.c b/gcc/testsuite/gcc.target/mips/inline-memcpy-3.c
new file mode 100644
index 00000000000..96a0387fce5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-3.c
@@ -0,0 +1,18 @@
+/* { dg-options "-fno-common isa_rev<=5" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os"} { "" } } */
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+/* { dg-final { scan-assembler-times "swl" 8 } } */
+/* { dg-final { scan-assembler-times "swr" 8 } } */
+
+/* Test that inline memcpy for hardware with swl, swr handles subword
+ alignment and produces enough swl/swrs for mips32. */
+
+#include <string.h>
+
+char c[40] __attribute__ ((aligned(2)));
+
+void
+f1 ()
+{
+ memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32);
+}
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-4.c b/gcc/testsuite/gcc.target/mips/inline-memcpy-4.c
new file mode 100644
index 00000000000..0e7a22e8a33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-4.c
@@ -0,0 +1,18 @@
+/* { dg-options "-fno-common isa_rev<=5 -mabi=64" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os"} { "" } } */
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+/* { dg-final { scan-assembler-times "sdl" 4 } } */
+/* { dg-final { scan-assembler-times "sdr" 4 } } */
+
+/* Test that inline memcpy for hardware with sdl, sdr handles subword
+ alignment and produces enough sdl/sdrs on n64. */
+
+#include <string.h>
+
+char c[40] __attribute__ ((aligned(2)));
+
+void
+f1 ()
+{
+ memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32);
+}
diff --git a/gcc/testsuite/gcc.target/mips/inline-memcpy-5.c b/gcc/testsuite/gcc.target/mips/inline-memcpy-5.c
new file mode 100644
index 00000000000..1b9fa16b2a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/inline-memcpy-5.c
@@ -0,0 +1,18 @@
+/* { dg-options "-fno-common isa_rev<=5 -mabi=n32" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os"} { "" } } */
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+/* { dg-final { scan-assembler-times "sdl" 4 } } */
+/* { dg-final { scan-assembler-times "sdr" 4 } } */
+
+/* Test that inline memcpy for hardware with sdl, sdr handles subword
+ alignment and produces enough sdr/sdls on n32. */
+
+#include <string.h>
+
+char c[40] __attribute__ ((aligned(2)));
+
+void
+f1 ()
+{
+ memcpy (c, "1234567890QWERTYUIOPASDFGHJKLZXCVBNM", 32);
+}