* config/aarch64/aarch64.md (movprfx): New attr.
(length): Default movprfx to 8.
* config/aarch64/aarch64-sve.md (*mul<SVE_I>3): Add movprfx alt.
(*madd<SVE_I>, *msub<SVE_I): Likewise.
(*<su>mul<SVE_I>3_highpart): Likewise.
(*<SVE_INT_BINARY_SD><SVE_SDI>3): Likewise.
(*v<ASHIFT><SVE_I>3): Likewise.
(*<su><MAXMIN><SVE_I>3): Likewise.
(*<su><MAXMIN><SVE_F>3): Likewise.
(*fma<SVE_F>4, *fnma<SVE_F>4): Likewise.
(*fms<SVE_F>4, *fnms<SVE_F>4): Likewise.
(*div<SVE_F>4): Likewise.
---
gcc/config/aarch64/aarch64-sve.md | 184 ++++++++++++++++++------------
gcc/config/aarch64/aarch64.md | 11 +-
2 files changed, 116 insertions(+), 79 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-sve.md
b/gcc/config/aarch64/aarch64-sve.md
index 8e2433385a8..3dee6a4376d 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -937,47 +937,53 @@
;; to gain much and would make the instruction seem less uniform to the
;; register allocator.
(define_insn "*mul<mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
(unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
(mult:SVE_I
- (match_operand:SVE_I 2 "register_operand" "%0, 0")
- (match_operand:SVE_I 3 "aarch64_sve_mul_operand" "vsm, w"))]
+ (match_operand:SVE_I 2 "register_operand" "%0, 0, w")
+ (match_operand:SVE_I 3 "aarch64_sve_mul_operand" "vsm, w, w"))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
mul\t%0.<Vetype>, %0.<Vetype>, #%3
- mul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ mul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;mul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
(define_insn "*madd<mode>"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
(plus:SVE_I
(unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w")
- (match_operand:SVE_I 3 "register_operand" "w, w"))]
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
UNSPEC_MERGE_PTRUE)
- (match_operand:SVE_I 4 "register_operand" "w, 0")))]
+ (match_operand:SVE_I 4 "register_operand" "w, 0, w")))]
"TARGET_SVE"
"@
mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
- mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
+ mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %4\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
(define_insn "*msub<mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
(minus:SVE_I
- (match_operand:SVE_I 4 "register_operand" "w, 0")
+ (match_operand:SVE_I 4 "register_operand" "w, 0, w")
(unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w")
- (match_operand:SVE_I 3 "register_operand" "w, w"))]
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
UNSPEC_MERGE_PTRUE)))]
"TARGET_SVE"
"@
msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
- mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
+ mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %4\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
;; Unpredicated highpart multiplication.
@@ -997,15 +1003,18 @@
;; Predicated highpart multiplication.
(define_insn "*<su>mul<mode>3_highpart"
- [(set (match_operand:SVE_I 0 "register_operand" "=w")
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
(unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (unspec:SVE_I [(match_operand:SVE_I 2 "register_operand" "%0")
- (match_operand:SVE_I 3 "register_operand" "w")]
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (unspec:SVE_I [(match_operand:SVE_I 2 "register_operand" "%0, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w")]
MUL_HIGHPART)]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
- "<su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ "@
+ <su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;<su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Unpredicated division.
@@ -1025,17 +1034,19 @@
;; Division predicated with a PTRUE.
(define_insn "*<optab><mode>3"
- [(set (match_operand:SVE_SDI 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_SDI 0 "register_operand" "=w, w, ?&w")
(unspec:SVE_SDI
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
(SVE_INT_BINARY_SD:SVE_SDI
- (match_operand:SVE_SDI 2 "register_operand" "0, w")
- (match_operand:SVE_SDI 3 "aarch64_sve_mul_operand" "w, 0"))]
+ (match_operand:SVE_SDI 2 "register_operand" "0, w, w")
+ (match_operand:SVE_SDI 3 "aarch64_sve_mul_operand" "w, 0, w"))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- <sve_int_op>r\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
+ <sve_int_op>r\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
;; Unpredicated NEG, NOT and POPCOUNT.
@@ -1222,17 +1233,19 @@
;; or X isn't likely to gain much and would make the instruction seem
;; less uniform to the register allocator.
(define_insn "*v<optab><mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
(unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
(ASHIFT:SVE_I
- (match_operand:SVE_I 2 "register_operand" "w, 0")
- (match_operand:SVE_I 3 "aarch64_sve_<lr>shift_operand" "D<lr>,
w"))]
+ (match_operand:SVE_I 2 "register_operand" "w, 0, w")
+ (match_operand:SVE_I 3 "aarch64_sve_<lr>shift_operand" "D<lr>, w,
w"))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
<shift>\t%0.<Vetype>, %2.<Vetype>, #%3
- <shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ <shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
;; LSL, LSR and ASR by a scalar, which expands into one of the vector
@@ -1723,14 +1736,17 @@
;; Integer MIN/MAX predicated with a PTRUE.
(define_insn "*<su><maxmin><mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w")
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
(unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (MAXMIN:SVE_I (match_operand:SVE_I 2 "register_operand" "%0")
- (match_operand:SVE_I 3 "register_operand" "w"))]
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (MAXMIN:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w"))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
- "<su><maxmin>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ "@
+ <su><maxmin>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;<su><maxmin>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Unpredicated floating-point MIN/MAX.
@@ -1749,14 +1765,17 @@
;; Floating-point MIN/MAX predicated with a PTRUE.
(define_insn "*<su><maxmin><mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w")
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
(unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (FMAXMIN:SVE_F (match_operand:SVE_F 2 "register_operand" "%0")
- (match_operand:SVE_F 3 "register_operand" "w"))]
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (FMAXMIN:SVE_F (match_operand:SVE_F 2 "register_operand" "%0, w")
+ (match_operand:SVE_F 3 "register_operand" "w, w"))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
- "f<maxmin>nm\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ "@
+ f<maxmin>nm\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;f<maxmin>nm\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Unpredicated fmin/fmax.
@@ -1776,15 +1795,18 @@
;; fmin/fmax predicated with a PTRUE.
(define_insn "*<maxmin_uns><mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w")
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
(unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (unspec:SVE_F [(match_operand:SVE_F 2 "register_operand" "%0")
- (match_operand:SVE_F 3 "register_operand" "w")]
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (unspec:SVE_F [(match_operand:SVE_F 2 "register_operand" "%0, w")
+ (match_operand:SVE_F 3 "register_operand" "w, w")]
FMAXMIN_UNS)]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
- "<maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ "@
+ <maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;<maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>,
%3.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
;; Predicated integer operations with select.
@@ -2146,17 +2168,19 @@
;; fma predicated with a PTRUE.
(define_insn "*fma<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
(unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (fma:SVE_F (match_operand:SVE_F 3 "register_operand" "%0, w")
- (match_operand:SVE_F 4 "register_operand" "w, w")
- (match_operand:SVE_F 2 "register_operand" "w, 0"))]
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (fma:SVE_F (match_operand:SVE_F 3 "register_operand" "%0, w, w")
+ (match_operand:SVE_F 4 "register_operand" "w, w, w")
+ (match_operand:SVE_F 2 "register_operand" "w, 0, w"))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
fmad\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
- fmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ fmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0, %2\;fmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
;; Unpredicated fnma (%0 = (-%1 * %2) + %3).
@@ -2177,18 +2201,20 @@
;; fnma predicated with a PTRUE.
(define_insn "*fnma<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
(unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
(fma:SVE_F (neg:SVE_F
- (match_operand:SVE_F 3 "register_operand" "%0, w"))
- (match_operand:SVE_F 4 "register_operand" "w, w")
- (match_operand:SVE_F 2 "register_operand" "w, 0"))]
+ (match_operand:SVE_F 3 "register_operand" "%0, w, w"))
+ (match_operand:SVE_F 4 "register_operand" "w, w, w")
+ (match_operand:SVE_F 2 "register_operand" "w, 0, w"))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
fmsb\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
- fmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ fmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0, %2\;fmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
;; Unpredicated fms (%0 = (%1 * %2) - %3).
@@ -2209,18 +2235,20 @@
;; fms predicated with a PTRUE.
(define_insn "*fms<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
(unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (fma:SVE_F (match_operand:SVE_F 3 "register_operand" "%0, w")
- (match_operand:SVE_F 4 "register_operand" "w, w")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (fma:SVE_F (match_operand:SVE_F 3 "register_operand" "%0, w, w")
+ (match_operand:SVE_F 4 "register_operand" "w, w, w")
(neg:SVE_F
- (match_operand:SVE_F 2 "register_operand" "w, 0")))]
+ (match_operand:SVE_F 2 "register_operand" "w, 0, w")))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
fnmsb\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
- fnmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ fnmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0, %2\;fnmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
;; Unpredicated fnms (%0 = (-%1 * %2) - %3).
@@ -2242,19 +2270,21 @@
;; fnms predicated with a PTRUE.
(define_insn "*fnms<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
(unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
(fma:SVE_F (neg:SVE_F
- (match_operand:SVE_F 3 "register_operand" "%0, w"))
- (match_operand:SVE_F 4 "register_operand" "w, w")
+ (match_operand:SVE_F 3 "register_operand" "%0, w, w"))
+ (match_operand:SVE_F 4 "register_operand" "w, w, w")
(neg:SVE_F
- (match_operand:SVE_F 2 "register_operand" "w, 0")))]
+ (match_operand:SVE_F 2 "register_operand" "w, 0, w")))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
fnmad\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
- fnmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ fnmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0, %2\;fnmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
;; Unpredicated floating-point division.
@@ -2273,16 +2303,18 @@
;; Floating-point division predicated with a PTRUE.
(define_insn "*div<mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
(unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (div:SVE_F (match_operand:SVE_F 2 "register_operand" "0, w")
- (match_operand:SVE_F 3 "register_operand" "w, 0"))]
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (div:SVE_F (match_operand:SVE_F 2 "register_operand" "0, w, w")
+ (match_operand:SVE_F 3 "register_operand" "w, 0, w"))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
fdiv\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- fdivr\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
+ fdivr\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0, %2\;fdiv\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
;; Unpredicated FNEG, FABS and FSQRT.
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 4ac6332a200..a014a012cc1 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -251,9 +251,6 @@
;; will be disabled when !TARGET_SVE.
(define_attr "sve" "no,yes" (const_string "no"))
-(define_attr "length" ""
- (const_int 4))
-
;; Attribute that controls whether an alternative is enabled or not.
;; Currently it is only used to disable alternatives which touch fp or simd
;; registers when -mgeneral-regs-only is specified.
@@ -277,6 +274,14 @@
;; 1 :=: yes
(define_attr "far_branch" "" (const_int 0))
+;; Attribute that specifies whether the alternative uses MOVPRFX.
+(define_attr "movprfx" "no,yes" (const_string "no"))
+
+(define_attr "length" ""
+ (cond [(eq_attr "movprfx" "yes")
+ (const_int 8)
+ ] (const_int 4)))
+
;; Strictly for compatibility with AArch32 in pipeline models, since AArch64
has
;; no predicated insns.
(define_attr "predicated" "yes,no" (const_string "no"))
--
2.17.1