Hi!
On Tue, Jul 13, 2021 at 12:14:22PM -0500, Peter Bergner wrote:
> +/* If the target storage locations of arguments MEM1 and MEM2 are
> + adjacent, then return the argument that has the lower address.
> + Otherwise, return NULL_RTX. */
>
> -static bool
> +static rtx
> adjacent_mem_locations (rtx mem1, rtx mem2)
Note that the function name now nly makes much sense if you use the
return value as a boolean (zero for false, non-zero for true).
> @@ -18633,7 +18639,7 @@ power6_sched_reorder2 (rtx_insn **ready, int lastpos)
> first_store_pos = pos;
>
> if (is_store_insn (last_scheduled_insn, &str_mem2)
> - && adjacent_mem_locations (str_mem, str_mem2))
> + && adjacent_mem_locations (str_mem, str_mem2) != NULL_RTX)
... so don't change this? Or write != 0 != 0 != 0, if one time is good,
three times must be better! :-)
> @@ -26752,13 +26758,53 @@ rs6000_split_multireg_move (rtx dst, rtx src)
> if (GET_MODE (src) == OOmode)
> gcc_assert (VSX_REGNO_P (REGNO (dst)));
>
> - reg_mode = GET_MODE (XVECEXP (src, 0, 0));
> int nvecs = XVECLEN (src, 0);
> for (int i = 0; i < nvecs; i++)
> {
> - int index = WORDS_BIG_ENDIAN ? i : nvecs - 1 - i;
> - rtx dst_i = gen_rtx_REG (reg_mode, reg + index);
> - emit_insn (gen_rtx_SET (dst_i, XVECEXP (src, 0, i)));
> + rtx op;
> + int regno = reg + i;
> +
> + if (WORDS_BIG_ENDIAN)
> + {
> + op = XVECEXP (src, 0, i);
> +
> + /* If we are loading an even VSX register and the memory
> location
> + is adjacent to the next register's memory location (if
> any),
> + then we can load them both with one LXVP instruction. */
> + if ((regno & 1) == 0)
> + {
> + rtx op2 = XVECEXP (src, 0, i + 1);
> + if (adjacent_mem_locations (op, op2) == op)
> + {
> + op = adjust_address (op, OOmode, 0);
> + /* Skip the next register, since we're going to
> + load it together with this register. */
> + i++;
> + }
> + }
> + }
> + else
> + {
> + op = XVECEXP (src, 0, nvecs - i - 1);
> +
> + /* If we are loading an even VSX register and the memory
> location
> + is adjacent to the next register's memory location (if
> any),
> + then we can load them both with one LXVP instruction. */
> + if ((regno & 1) == 0)
> + {
> + rtx op2 = XVECEXP (src, 0, nvecs - i - 2);
> + if (adjacent_mem_locations (op2, op) == op2)
> + {
> + op = adjust_address (op2, OOmode, 0);
> + /* Skip the next register, since we're going to
> + load it together with this register. */
> + i++;
> + }
> + }
> + }
> +
> + rtx dst_i = gen_rtx_REG (GET_MODE (op), regno);
> + emit_insn (gen_rtx_SET (dst_i, op));
> }
So we are sure we have a hard register here, and it is a VSX register.
Okay. Factoring this code would not hurt ;-)
Okay for trunk. Thanks!
Segher