Commit c8241327 by Aaron Sawdey Committed by Aaron Sawdey

rs6000-protos.h (expand_block_move): Change prototype.

2019-10-02  Aaron Sawdey <acsawdey@linux.ibm.com>

	* config/rs6000/rs6000-protos.h (expand_block_move): Change prototype.
	* config/rs6000/rs6000-string.c (expand_block_move): Add
	might_overlap parm.
	* config/rs6000/rs6000.md (movmemsi): Add new pattern.
	(cpymemsi): Add might_overlap parm to expand_block_move() call.

From-SVN: r276462
parent 03a9b90a
2019-10-02 Aaron Sawdey <acsawdey@linux.ibm.com> 2019-10-02 Aaron Sawdey <acsawdey@linux.ibm.com>
* config/rs6000/rs6000-protos.h (expand_block_move): Change prototype.
* config/rs6000/rs6000-string.c (expand_block_move): Add
might_overlap parm.
* config/rs6000/rs6000.md (movmemsi): Add new pattern.
(cpymemsi): Add might_overlap parm to expand_block_move() call.
2019-10-02 Aaron Sawdey <acsawdey@linux.ibm.com>
* builtins.c (expand_builtin_memory_copy_args): Add might_overlap parm. * builtins.c (expand_builtin_memory_copy_args): Add might_overlap parm.
(expand_builtin_memcpy): Use might_overlap parm. (expand_builtin_memcpy): Use might_overlap parm.
(expand_builtin_mempcpy_args): Use might_overlap parm. (expand_builtin_mempcpy_args): Use might_overlap parm.
......
...@@ -69,7 +69,7 @@ extern void rs6000_generate_float2_code (bool, rtx, rtx, rtx); ...@@ -69,7 +69,7 @@ extern void rs6000_generate_float2_code (bool, rtx, rtx, rtx);
extern void rs6000_generate_float2_double_code (rtx, rtx, rtx); extern void rs6000_generate_float2_double_code (rtx, rtx, rtx);
extern void rs6000_generate_vsigned2_code (bool, rtx, rtx, rtx); extern void rs6000_generate_vsigned2_code (bool, rtx, rtx, rtx);
extern int expand_block_clear (rtx[]); extern int expand_block_clear (rtx[]);
extern int expand_block_move (rtx[]); extern int expand_block_move (rtx[], bool);
extern bool expand_block_compare (rtx[]); extern bool expand_block_compare (rtx[]);
extern bool expand_strn_compare (rtx[], int); extern bool expand_strn_compare (rtx[], int);
extern bool rs6000_is_valid_mask (rtx, int *, int *, machine_mode); extern bool rs6000_is_valid_mask (rtx, int *, int *, machine_mode);
......
...@@ -2719,7 +2719,7 @@ gen_lvx_v4si_move (rtx dest, rtx src) ...@@ -2719,7 +2719,7 @@ gen_lvx_v4si_move (rtx dest, rtx src)
#define MAX_MOVE_REG 4 #define MAX_MOVE_REG 4
int int
expand_block_move (rtx operands[]) expand_block_move (rtx operands[], bool might_overlap)
{ {
rtx orig_dest = operands[0]; rtx orig_dest = operands[0];
rtx orig_src = operands[1]; rtx orig_src = operands[1];
...@@ -2730,6 +2730,7 @@ expand_block_move (rtx operands[]) ...@@ -2730,6 +2730,7 @@ expand_block_move (rtx operands[])
int bytes; int bytes;
int offset; int offset;
int move_bytes; int move_bytes;
rtx loads[MAX_MOVE_REG];
rtx stores[MAX_MOVE_REG]; rtx stores[MAX_MOVE_REG];
int num_reg = 0; int num_reg = 0;
...@@ -2817,47 +2818,35 @@ expand_block_move (rtx operands[]) ...@@ -2817,47 +2818,35 @@ expand_block_move (rtx operands[])
gen_func.mov = gen_movqi; gen_func.mov = gen_movqi;
} }
/* Mode is always set to something other than BLKmode by one of the
cases of the if statement above. */
gcc_assert (mode != BLKmode);
src = adjust_address (orig_src, mode, offset); src = adjust_address (orig_src, mode, offset);
dest = adjust_address (orig_dest, mode, offset); dest = adjust_address (orig_dest, mode, offset);
if (mode != BLKmode) rtx tmp_reg = gen_reg_rtx (mode);
{
rtx tmp_reg = gen_reg_rtx (mode); loads[num_reg] = (*gen_func.mov) (tmp_reg, src);
stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
emit_insn ((*gen_func.mov) (tmp_reg, src)); /* If we didn't succeed in doing it in one pass, we can't do it in the
stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg); might_overlap case. Bail out and return failure. */
} if (might_overlap && num_reg >= MAX_MOVE_REG
&& bytes > move_bytes)
return 0;
if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes) /* Emit loads and stores saved up. */
if (num_reg >= MAX_MOVE_REG || bytes == move_bytes)
{ {
int i; int i;
for (i = 0; i < num_reg; i++) for (i = 0; i < num_reg; i++)
emit_insn (loads[i]);
for (i = 0; i < num_reg; i++)
emit_insn (stores[i]); emit_insn (stores[i]);
num_reg = 0; num_reg = 0;
} }
if (mode == BLKmode)
{
/* Move the address into scratch registers. The movmemsi
patterns require zero offset. */
if (!REG_P (XEXP (src, 0)))
{
rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
src = replace_equiv_address (src, src_reg);
}
set_mem_size (src, move_bytes);
if (!REG_P (XEXP (dest, 0)))
{
rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
dest = replace_equiv_address (dest, dest_reg);
}
set_mem_size (dest, move_bytes);
emit_insn ((*gen_func.movmemsi) (dest, src,
GEN_INT (move_bytes & 31),
align_rtx));
}
} }
return 1; return 1;
......
...@@ -9107,7 +9107,7 @@ ...@@ -9107,7 +9107,7 @@
FAIL; FAIL;
}) })
;; String/block move insn. ;; String/block copy insn (source and destination must not overlap).
;; Argument 0 is the destination ;; Argument 0 is the destination
;; Argument 1 is the source ;; Argument 1 is the source
;; Argument 2 is the length ;; Argument 2 is the length
...@@ -9120,11 +9120,31 @@ ...@@ -9120,11 +9120,31 @@
(use (match_operand:SI 3 ""))])] (use (match_operand:SI 3 ""))])]
"" ""
{ {
if (expand_block_move (operands)) if (expand_block_move (operands, false))
DONE; DONE;
else else
FAIL; FAIL;
}) })
;; String/block move insn (source and destination may overlap).
;; Argument 0 is the destination
;; Argument 1 is the source
;; Argument 2 is the length
;; Argument 3 is the alignment
(define_expand "movmemsi"
[(parallel [(set (match_operand:BLK 0 "")
(match_operand:BLK 1 ""))
(use (match_operand:SI 2 ""))
(use (match_operand:SI 3 ""))])]
""
{
if (expand_block_move (operands, true))
DONE;
else
FAIL;
})
;; Define insns that do load or store with update. Some of these we can ;; Define insns that do load or store with update. Some of these we can
;; get by using pre-decrement or pre-increment, but the hardware can also ;; get by using pre-decrement or pre-increment, but the hardware can also
......
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