@@ -242,7 +242,7 @@ extern bool mips_get_pic_call_symbol (rtx *, int);
extern void mips_set_return_address (rtx, rtx);
extern bool mips_move_by_pieces_p (unsigned HOST_WIDE_INT, unsigned int);
extern bool mips_store_by_pieces_p (unsigned HOST_WIDE_INT, unsigned int);
-extern bool mips_expand_block_move (rtx, rtx, rtx);
+extern bool mips_expand_block_move (rtx, rtx, rtx, rtx);
extern void mips_expand_synci_loop (rtx, rtx);
extern void mips_init_cumulative_args (CUMULATIVE_ARGS *, tree);
@@ -9472,7 +9472,7 @@ mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
memory reference SRC to memory reference DEST. */
bool
-mips_expand_block_move (rtx dest, rtx src, rtx length)
+mips_expand_block_move (rtx dest, rtx src, rtx length, rtx alignment)
{
if (!CONST_INT_P (length))
return false;
@@ -9482,16 +9482,25 @@ mips_expand_block_move (rtx dest, rtx src, rtx length)
|| MEM_ALIGN (dest) < MIPS_MIN_MOVE_MEM_ALIGN))
return false;
- if (INTVAL (length) <= MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER)
+ if (mips_movmem_limit == -1 || INTVAL (length) < mips_movmem_limit)
{
- mips_block_move_straight (dest, src, INTVAL (length));
- return true;
- }
- else if (optimize)
- {
- mips_block_move_loop (dest, src, INTVAL (length),
- MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER);
- return true;
+ if (INTVAL (length) <= MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER
+ /* We increase slightly the maximum number of bytes in
+ a straight-line block if the source and destination
+ are aligned to the register width. */
+ || (!optimize_size
+ && INTVAL (alignment) == UNITS_PER_WORD
+ && INTVAL (length) <= MIPS_MAX_MOVE_MEM_STRAIGHT))
+ {
+ mips_block_move_straight (dest, src, INTVAL (length));
+ return true;
+ }
+ else if (optimize)
+ {
+ mips_block_move_loop (dest, src, INTVAL (length),
+ MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER);
+ return true;
+ }
}
return false;
@@ -3158,6 +3158,11 @@ while (0)
#define MIPS_MAX_MOVE_BYTES_STRAIGHT \
(MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER * 2)
+/* The maximum number of bytes that can be copied by any expanded block move;
+ see mips_expand_block_move. */
+#define MIPS_MAX_MOVE_MEM_STRAIGHT \
+ (MIPS_MAX_MOVE_BYTES_PER_LOOP_ITER * 3)
+
/* The base cost of a memcpy call, for MOVE_RATIO and friends. These
values were determined experimentally by benchmarking with CSiBE.
In theory, the call overhead is higher for TARGET_ABICALLS (especially
@@ -5875,7 +5875,7 @@
(use (match_operand:SI 3 "const_int_operand"))])]
"!TARGET_MIPS16 && !TARGET_MEMCPY"
{
- if (mips_expand_block_move (operands[0], operands[1], operands[2]))
+ if (mips_expand_block_move (operands[0], operands[1], operands[2], operands[3]))
DONE;
else
FAIL;
@@ -550,6 +550,9 @@ mfunc-opt-list=
Target RejectNegative Joined Var(mips_func_opt_list_file) Init(0) Defer
mfunc-opt-list=FILE Use to specify per function optimizations.
+mblockmov-limit=
+Target RejectNegative Undocumented Joined UInteger Var(mips_movmem_limit) Init(-1)
+
minline-intermix
Target Var(TARGET_INLINE_INTERMIX)
Allow inlining even if the compression flags differ between caller and callee.
@@ -1,7 +1,7 @@
/* Check that typedef alignment does not affect passing of function
parameters for O32 ABI. */
/* { dg-do compile { target { "mips*-*-*" } } } */
-/* { dg-options "-mabi=32" } */
+/* { dg-options "-mabi=32 -mblockmov-limit=0" } */
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
typedef struct ui8
new file mode 100644
@@ -0,0 +1,17 @@
+/* { dg-options "-mabi=32 -mblockmov-limit=16" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" } { "" } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } } */
+
+/* -mblockmov-limit should prevent a constant-sized copy at the limit from
+ being expanded inline. */
+
+unsigned int a[4];
+unsigned int b[4];
+
+NOCOMPRESSION void
+foo (void)
+{
+ __builtin_memcpy (a, b, sizeof (a));
+}
+
+/* { dg-final { scan-assembler "\tmemcpy" } } */
new file mode 100644
@@ -0,0 +1,18 @@
+/* { dg-options "-mabi=32" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" } { "" } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } } */
+
+/* A word-aligned copy of up to MIPS_MAC_MOVE_MEM_STRAIGHT bytes should be
+ expanded as straight-line code rather than as block-move loop. */
+
+unsigned int a[4];
+unsigned int b[4];
+
+NOCOMPRESSION void
+foo (void)
+{
+ __builtin_memcpy (a, b, sizeof (a));
+}
+
+/* { dg-final { scan-assembler-not "\tmemcpy" } } */
+/* { dg-final { scan-assembler-not "\tbne\t" } } */
@@ -312,6 +312,7 @@ foreach option {
# Add -mfoo= options to mips_option_groups.
foreach option {
abs
+ blockmov-limit
branch-cost
code-readable
func-opt-list