[aarch64,1/4] aarch64: Add movprfx alternatives for unpredicated patterns

Message ID 20180702034133.12511-2-rth@twiddle.net
State New
Headers show
Series
  • Add movprfx patterns and alternatives
Related show

Commit Message

Richard Henderson July 2, 2018, 3:41 a.m.
* 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(-)

-- 
2.17.1

Comments

Richard Sandiford July 2, 2018, 11:56 a.m. | #1
Richard Henderson <rth@twiddle.net> writes:
> 	* 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.


OK, thanks.

Richard

> ---

>  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"))

Patch

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"))