Commit 58df0b91 by Simon Dardis Committed by Simon Dardis

mips.c (mips_expand_block_move): Enable inline memcpy expansion when !ISA_HAS_LWL_LWR.

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.

From-SVN: r227026
parent 95f25df0
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
......
......@@ -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))
......
......@@ -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 \
......
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.
......
/* { 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);
}
/* { 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);
}
/* { 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);
}
/* { 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);
}
/* { 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment