diff options
author | Aaron Sawdey <acsawdey@linux.ibm.com> | 2019-10-02 14:26:09 +0000 |
---|---|---|
committer | Aaron Sawdey <acsawdey@gcc.gnu.org> | 2019-10-02 09:26:09 -0500 |
commit | c8241327cd156ed15fb136e0b0eaace263aba717 (patch) | |
tree | 077e7990fb39b4ec5c3e90f8be904e43270bc957 /gcc | |
parent | 03a9b90aa6df28dde083efd17e8b7ae76b943fe7 (diff) | |
download | gcc-c8241327cd156ed15fb136e0b0eaace263aba717.zip gcc-c8241327cd156ed15fb136e0b0eaace263aba717.tar.gz gcc-c8241327cd156ed15fb136e0b0eaace263aba717.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-string.c | 51 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 24 |
4 files changed, 51 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe14577..5dc5331 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 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. (expand_builtin_memcpy): Use might_overlap parm. (expand_builtin_mempcpy_args): Use might_overlap parm. diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index c51b768..08dd88c 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -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_vsigned2_code (bool, rtx, rtx, 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_strn_compare (rtx[], int); extern bool rs6000_is_valid_mask (rtx, int *, int *, machine_mode); diff --git a/gcc/config/rs6000/rs6000-string.c b/gcc/config/rs6000/rs6000-string.c index b939185..3bc359e 100644 --- a/gcc/config/rs6000/rs6000-string.c +++ b/gcc/config/rs6000/rs6000-string.c @@ -2719,7 +2719,7 @@ gen_lvx_v4si_move (rtx dest, rtx src) #define MAX_MOVE_REG 4 int -expand_block_move (rtx operands[]) +expand_block_move (rtx operands[], bool might_overlap) { rtx orig_dest = operands[0]; rtx orig_src = operands[1]; @@ -2730,6 +2730,7 @@ expand_block_move (rtx operands[]) int bytes; int offset; int move_bytes; + rtx loads[MAX_MOVE_REG]; rtx stores[MAX_MOVE_REG]; int num_reg = 0; @@ -2817,47 +2818,35 @@ expand_block_move (rtx operands[]) 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); 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)); - stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg); - } + /* If we didn't succeed in doing it in one pass, we can't do it in the + 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; for (i = 0; i < num_reg; i++) + emit_insn (loads[i]); + for (i = 0; i < num_reg; i++) emit_insn (stores[i]); 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; diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 4f27f13..2dca269 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -9107,7 +9107,7 @@ FAIL; }) -;; String/block move insn. +;; String/block copy insn (source and destination must not overlap). ;; Argument 0 is the destination ;; Argument 1 is the source ;; Argument 2 is the length @@ -9120,11 +9120,31 @@ (use (match_operand:SI 3 ""))])] "" { - if (expand_block_move (operands)) + if (expand_block_move (operands, false)) DONE; else 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 ;; get by using pre-decrement or pre-increment, but the hardware can also |