diff mbox series

[1/2] Move xx* builtins to vsx.md.

Message ID 20210518204647.GA16671@ibm-toto.the-meissners.org
State New
Headers show
Series Move xx* builtins to vsx.md. | expand

Commit Message

Michael Meissner May 18, 2021, 8:46 p.m. UTC
[PATCH 1/2] Move xx* builtins to vsx.md.

I noticed that the xx built-in functions (xxspltiw, xxspltidp, xxsplti32dx,
xxeval, xxblend, and xxpermx) were all defined in altivec.md.  However, since
the XX instructions can take both traditional floating point and Altivec
registers, these built-in functions should be in vsx.md.

This patch just moves the insns from altivec.md to vsx.md.

I also moved the VM3 mode iterator and VM3_char mode attribute from altivec.md
to vsx.md, since the only use of these were for the XXBLEND insns.

I have bootstraped this on LE power9 and BE power8 systems.  There were no
regressions in the tests.  Can I check this into the trunk?

I do not expect to back port this to GCC 11 unless we will be back porting the
future patches that add support for the XXSPLITW, XXSPLTIDP, and XXSPLTI32DX
instructions.

gcc/
2021-05-18  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/altivec.md (UNSPEC_XXEVAL): Move to vsx.md.
	(UNSPEC_XXSPLTIW): Move to vsx.md.
	(UNSPEC_XXSPLTID): Move to vsx.md.
	(UNSPEC_XXSPLTI32DX): Move to vsx.md.
	(UNSPEC_XXBLEND): Move to vsx.md.
	(UNSPEC_XXPERMX): Move to vsx.md.
	(VM3): Move to vsx.md.
	(VM3_char): Move to vsx.md.
	(xxspltiw_v4si): Move to vsx.md.
	(xxspltiw_v4sf): Move to vsx.md.
	(xxspltiw_v4sf_inst): Move to vsx.md.
	(xxspltidp_v2df): Move to vsx.md.
	(xxspltidp_v2df_inst): Move to vsx.md.
	(xxsplti32dx_v4si_inst): Move to vsx.md.
	(xxsplti32dx_v4sf): Move to vsx.md.
	(xxsplti32dx_v4sf_inst): Move to vsx.md.
	(xxblend_<mode>): Move to vsx.md.
	(xxpermx): Move to vsx.md.
	(xxpermx_inst): Move to vsx.md.
	* config/rs6000/vsx.md (UNSPEC_XXEVAL): Move from altivec.md.
	(UNSPEC_XXSPLTIW): Move from altivec.md.
	(UNSPEC_XXSPLTID): Move from altivec.md.
	(UNSPEC_XXSPLTI32DX): Move from altivec.md.
	(UNSPEC_XXBLEND): Move from altivec.md.
	(UNSPEC_XXPERMX): Move from altivec.md.
	(VM3): Move from altivec.md.
	(VM3_char): Move from altivec.md.
	(xxspltiw_v4si): Move from altivec.md.
	(xxspltiw_v4sf): Move from altivec.md.
	(xxspltiw_v4sf_inst): Move from altivec.md.
	(xxspltidp_v2df): Move from altivec.md.
	(xxspltidp_v2df_inst): Move from altivec.md.
	(xxsplti32dx_v4si_inst): Move from altivec.md.
	(xxsplti32dx_v4sf): Move from altivec.md.
	(xxsplti32dx_v4sf_inst): Move from altivec.md.
	(xxblend_<mode>): Move from altivec.md.
	(xxpermx): Move from altivec.md.
	(xxpermx_inst): Move from altivec.md.
---
 gcc/config/rs6000/altivec.md | 196 ---------------------------------
 gcc/config/rs6000/vsx.md     | 204 +++++++++++++++++++++++++++++++++++
 2 files changed, 204 insertions(+), 196 deletions(-)

Comments

will schmidt May 20, 2021, 7:30 p.m. UTC | #1
On Tue, 2021-05-18 at 16:46 -0400, Michael Meissner wrote:
> [PATCH 1/2] Move xx* builtins to vsx.md.
> 

Hi,


> I noticed that the xx built-in functions (xxspltiw, xxspltidp, xxsplti32dx,
> xxeval, xxblend, and xxpermx) were all defined in altivec.md.  However, since
> the XX instructions can take both traditional floating point and Altivec
> registers, these built-in functions should be in vsx.md.
> 
> This patch just moves the insns from altivec.md to vsx.md.
> 
> I also moved the VM3 mode iterator and VM3_char mode attribute from altivec.md
> to vsx.md, since the only use of these were for the XXBLEND insns.
> 
> I have bootstraped this on LE power9 and BE power8 systems.  There were no
> regressions in the tests.  Can I check this into the trunk?
> 
> I do not expect to back port this to GCC 11 unless we will be back porting the
> future patches that add support for the XXSPLITW, XXSPLTIDP, and XXSPLTI32DX
> instructions.
> 
> gcc/
> 2021-05-18  Michael Meissner  <meissner@linux.ibm.com>
> 
> 	* config/rs6000/altivec.md (UNSPEC_XXEVAL): Move to vsx.md.
> 	(UNSPEC_XXSPLTIW): Move to vsx.md.
> 	(UNSPEC_XXSPLTID): Move to vsx.md.
> 	(UNSPEC_XXSPLTI32DX): Move to vsx.md.
> 	(UNSPEC_XXBLEND): Move to vsx.md.
> 	(UNSPEC_XXPERMX): Move to vsx.md.
> 	(VM3): Move to vsx.md.
> 	(VM3_char): Move to vsx.md.
> 	(xxspltiw_v4si): Move to vsx.md.
> 	(xxspltiw_v4sf): Move to vsx.md.
> 	(xxspltiw_v4sf_inst): Move to vsx.md.
> 	(xxspltidp_v2df): Move to vsx.md.
> 	(xxspltidp_v2df_inst): Move to vsx.md.
> 	(xxsplti32dx_v4si_inst): Move to vsx.md.
> 	(xxsplti32dx_v4sf): Move to vsx.md.
> 	(xxsplti32dx_v4sf_inst): Move to vsx.md.
> 	(xxblend_<mode>): Move to vsx.md.
> 	(xxpermx): Move to vsx.md.
> 	(xxpermx_inst): Move to vsx.md.
> 	* config/rs6000/vsx.md (UNSPEC_XXEVAL): Move from altivec.md.
> 	(UNSPEC_XXSPLTIW): Move from altivec.md.
> 	(UNSPEC_XXSPLTID): Move from altivec.md.
> 	(UNSPEC_XXSPLTI32DX): Move from altivec.md.
> 	(UNSPEC_XXBLEND): Move from altivec.md.
> 	(UNSPEC_XXPERMX): Move from altivec.md.
> 	(VM3): Move from altivec.md.
> 	(VM3_char): Move from altivec.md.
> 	(xxspltiw_v4si): Move from altivec.md.
> 	(xxspltiw_v4sf): Move from altivec.md.
> 	(xxspltiw_v4sf_inst): Move from altivec.md.
> 	(xxspltidp_v2df): Move from altivec.md.
> 	(xxspltidp_v2df_inst): Move from altivec.md.
> 	(xxsplti32dx_v4si_inst): Move from altivec.md.
> 	(xxsplti32dx_v4sf): Move from altivec.md.
> 	(xxsplti32dx_v4sf_inst): Move from altivec.md.
> 	(xxblend_<mode>): Move from altivec.md.
> 	(xxpermx): Move from altivec.md.
> 	(xxpermx_inst): Move from altivec.md.
> ---
>  gcc/config/rs6000/altivec.md | 196 ---------------------------------
>  gcc/config/rs6000/vsx.md     | 204 +++++++++++++++++++++++++++++++++++
>  2 files changed, 204 insertions(+), 196 deletions(-)
> 
> diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
> index 1351dafbc41..8a9f55c561b 100644
> --- a/gcc/config/rs6000/altivec.md
> +++ b/gcc/config/rs6000/altivec.md
> @@ -171,16 +171,10 @@ (define_c_enum "unspec"
>     UNSPEC_VPEXTD
>     UNSPEC_VCLRLB
>     UNSPEC_VCLRRB
> -   UNSPEC_XXEVAL
>     UNSPEC_VSTRIR
>     UNSPEC_VSTRIL
>     UNSPEC_SLDB
>     UNSPEC_SRDB
> -   UNSPEC_XXSPLTIW
> -   UNSPEC_XXSPLTID
> -   UNSPEC_XXSPLTI32DX
> -   UNSPEC_XXBLEND
> -   UNSPEC_XXPERMX
>  ])
> 
>  (define_c_enum "unspecv"
> @@ -221,21 +215,6 @@ (define_mode_iterator VM2 [V4SI
>  			   (KF "FLOAT128_VECTOR_P (KFmode)")
>  			   (TF "FLOAT128_VECTOR_P (TFmode)")])
> 
> -;; Like VM2, just do char, short, int, long, float and double
> -(define_mode_iterator VM3 [V4SI
> -			   V8HI
> -			   V16QI
> -			   V4SF
> -			   V2DF
> -			   V2DI])
> -
> -(define_mode_attr VM3_char [(V2DI "d")
> -			   (V4SI "w")
> -			   (V8HI "h")
> -			   (V16QI "b")
> -			   (V2DF  "d")
> -			   (V4SF  "w")])
> -
>  ;; Map the Vector convert single precision to double precision for integer
>  ;; versus floating point
>  (define_mode_attr VS_sxwsp [(V4SI "sxw") (V4SF "sp")])
> @@ -820,169 +799,6 @@ (define_insn "vs<SLDB_lr>db_<mode>"
>    "vs<SLDB_lr>dbi %0,%1,%2,%3"
>    [(set_attr "type" "vecsimple")])
> 
> -(define_insn "xxspltiw_v4si"
> -  [(set (match_operand:V4SI 0 "register_operand" "=wa")
> -	(unspec:V4SI [(match_operand:SI 1 "s32bit_cint_operand" "n")]
> -		     UNSPEC_XXSPLTIW))]
> - "TARGET_POWER10"
> - "xxspltiw %x0,%1"
> - [(set_attr "type" "vecsimple")
> -  (set_attr "prefixed" "yes")])
> -
> -(define_expand "xxspltiw_v4sf"
> -  [(set (match_operand:V4SF 0 "register_operand" "=wa")
> -	(unspec:V4SF [(match_operand:SF 1 "const_double_operand" "n")]
> -		     UNSPEC_XXSPLTIW))]
> - "TARGET_POWER10"
> -{
> -  long long value = rs6000_const_f32_to_i32 (operands[1]);
> -  emit_insn (gen_xxspltiw_v4sf_inst (operands[0], GEN_INT (value)));
> -  DONE;
> -})
> -
> -(define_insn "xxspltiw_v4sf_inst"
> -  [(set (match_operand:V4SF 0 "register_operand" "=wa")
> -	(unspec:V4SF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
> -		     UNSPEC_XXSPLTIW))]
> - "TARGET_POWER10"
> - "xxspltiw %x0,%1"
> - [(set_attr "type" "vecsimple")
> -  (set_attr "prefixed" "yes")])
> -
> -(define_expand "xxspltidp_v2df"
> -  [(set (match_operand:V2DF 0 "register_operand" )
> -	(unspec:V2DF [(match_operand:SF 1 "const_double_operand")]
> -		     UNSPEC_XXSPLTID))]
> - "TARGET_POWER10"
> -{
> -  long value = rs6000_const_f32_to_i32 (operands[1]);
> -  rs6000_emit_xxspltidp_v2df (operands[0], value);
> -  DONE;
> -})
> -
> -(define_insn "xxspltidp_v2df_inst"
> -  [(set (match_operand:V2DF 0 "register_operand" "=wa")
> -	(unspec:V2DF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
> -		     UNSPEC_XXSPLTID))]
> -  "TARGET_POWER10"
> -  "xxspltidp %x0,%1"
> -  [(set_attr "type" "vecsimple")
> -   (set_attr "prefixed" "yes")])
> -
> -(define_expand "xxsplti32dx_v4si"
> -  [(set (match_operand:V4SI 0 "register_operand" "=wa")
> -	(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
> -		      (match_operand:QI 2 "u1bit_cint_operand" "n")
> -		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
> -		     UNSPEC_XXSPLTI32DX))]
> - "TARGET_POWER10"
> -{
> -  int index = INTVAL (operands[2]);
> -
> -  if (!BYTES_BIG_ENDIAN)
> -    index = 1 - index;
> -
> -   emit_insn (gen_xxsplti32dx_v4si_inst (operands[0], operands[1],
> -					 GEN_INT (index), operands[3]));
> -   DONE;
> -}
> - [(set_attr "type" "vecsimple")])
> -
> -(define_insn "xxsplti32dx_v4si_inst"
> -  [(set (match_operand:V4SI 0 "register_operand" "=wa")
> -	(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
> -		      (match_operand:QI 2 "u1bit_cint_operand" "n")
> -		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
> -		     UNSPEC_XXSPLTI32DX))]
> -  "TARGET_POWER10"
> -  "xxsplti32dx %x0,%2,%3"
> -  [(set_attr "type" "vecsimple")
> -   (set_attr "prefixed" "yes")])
> -
> -(define_expand "xxsplti32dx_v4sf"
> -  [(set (match_operand:V4SF 0 "register_operand" "=wa")
> -	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
> -		      (match_operand:QI 2 "u1bit_cint_operand" "n")
> -		      (match_operand:SF 3 "const_double_operand" "n")]
> -		     UNSPEC_XXSPLTI32DX))]
> -  "TARGET_POWER10"
> -{
> -  int index = INTVAL (operands[2]);
> -  long value = rs6000_const_f32_to_i32 (operands[3]);
> -  if (!BYTES_BIG_ENDIAN)
> -    index = 1 - index;
> -
> -   emit_insn (gen_xxsplti32dx_v4sf_inst (operands[0], operands[1],
> -					 GEN_INT (index), GEN_INT (value)));
> -   DONE;
> -})
> -
> -(define_insn "xxsplti32dx_v4sf_inst"
> -  [(set (match_operand:V4SF 0 "register_operand" "=wa")
> -	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
> -		      (match_operand:QI 2 "u1bit_cint_operand" "n")
> -		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
> -		     UNSPEC_XXSPLTI32DX))]
> -  "TARGET_POWER10"
> -  "xxsplti32dx %x0,%2,%3"
> -  [(set_attr "type" "vecsimple")
> -   (set_attr "prefixed" "yes")])
> -
> -(define_insn "xxblend_<mode>"
> -  [(set (match_operand:VM3 0 "register_operand" "=wa")
> -	(unspec:VM3 [(match_operand:VM3 1 "register_operand" "wa")
> -		     (match_operand:VM3 2 "register_operand" "wa")
> -		     (match_operand:VM3 3 "register_operand" "wa")]
> -		    UNSPEC_XXBLEND))]
> -  "TARGET_POWER10"
> -  "xxblendv<VM3_char> %x0,%x1,%x2,%x3"
> -  [(set_attr "type" "vecsimple")
> -   (set_attr "prefixed" "yes")])
> -
> -(define_expand "xxpermx"
> -  [(set (match_operand:V2DI 0 "register_operand" "+wa")
> -	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "wa")
> -		      (match_operand:V2DI 2 "register_operand" "wa")
> -		      (match_operand:V16QI 3 "register_operand" "wa")
> -		      (match_operand:QI 4 "u8bit_cint_operand" "n")]
> -		     UNSPEC_XXPERMX))]
> -  "TARGET_POWER10"
> -{
> -  if (BYTES_BIG_ENDIAN)
> -    emit_insn (gen_xxpermx_inst (operands[0], operands[1],
> -				 operands[2], operands[3],
> -				 operands[4]));
> -  else
> -    {
> -      /* Reverse value of byte element indexes by XORing with 0xFF.
> -	 Reverse the 32-byte section identifier match by subracting bits [0:2]
> -	 of elemet from 7.  */
> -      int value = INTVAL (operands[4]);
> -      rtx vreg = gen_reg_rtx (V16QImode);
> -
> -      emit_insn (gen_xxspltib_v16qi (vreg, GEN_INT (-1)));
> -      emit_insn (gen_xorv16qi3 (operands[3], operands[3], vreg));
> -      value = 7 - value;
> -      emit_insn (gen_xxpermx_inst (operands[0], operands[2],
> -				   operands[1], operands[3],
> -				   GEN_INT (value)));
> -    }
> -
> -  DONE;
> -}
> -  [(set_attr "type" "vecsimple")])
> -
> -(define_insn "xxpermx_inst"
> -  [(set (match_operand:V2DI 0 "register_operand" "+v")
> -	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v")
> -		      (match_operand:V2DI 2 "register_operand" "v")
> -		      (match_operand:V16QI 3 "register_operand" "v")
> -		      (match_operand:QI 4 "u3bit_cint_operand" "n")]
> -		     UNSPEC_XXPERMX))]
> -  "TARGET_POWER10"
> -  "xxpermx %x0,%x1,%x2,%x3,%4"
> -  [(set_attr "type" "vecsimple")
> -   (set_attr "prefixed" "yes")])
> 
>  (define_expand "vstrir_<mode>"
>    [(set (match_operand:VIshort 0 "altivec_register_operand")
> @@ -3621,18 +3437,6 @@ (define_insn "vperm_v16qiv8hi"
>    [(set_attr "type" "vecperm")
>     (set_attr "isa" "p9v,*")])
> 
> -(define_insn "xxeval"
> -  [(set (match_operand:V2DI 0 "register_operand" "=wa")
> -	(unspec:V2DI [(match_operand:V2DI 1 "altivec_register_operand" "wa")
> -		      (match_operand:V2DI 2 "altivec_register_operand" "wa")
> -		      (match_operand:V2DI 3 "altivec_register_operand" "wa")
> -		      (match_operand:QI 4 "u8bit_cint_operand" "n")]
> -		     UNSPEC_XXEVAL))]
> -   "TARGET_POWER10"
> -   "xxeval %0,%1,%2,%3,%4"
> -   [(set_attr "type" "vecsimple")
> -    (set_attr "prefixed" "yes")])
> -
>  (define_expand "vec_unpacku_hi_v16qi"
>    [(set (match_operand:V8HI 0 "register_operand" "=v")
>          (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
> diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
> index bcb92be2f5c..a859038d399 100644
> --- a/gcc/config/rs6000/vsx.md
> +++ b/gcc/config/rs6000/vsx.md
> @@ -271,6 +271,22 @@ (define_mode_iterator VSX_MM4 [V16QI V8HI V4SI V2DI])
>  ;; and Vector Integer Multiply/Divide/Modulo Instructions
>  (define_mode_iterator VIlong [V2DI V4SI])
> 
> +;; Like VM2 in altivec.md, just do char, short, int, long, float and double
> +(define_mode_iterator VM3 [V4SI
> +			   V8HI
> +			   V16QI
> +			   V4SF
> +			   V2DF
> +			   V2DI])
> +
> +(define_mode_attr VM3_char [(V2DI "d")
> +			   (V4SI  "w")
> +			   (V8HI  "h")
> +			   (V16QI "b")
> +			   (V2DF  "d")
> +			   (V4SF  "w")])
> +
> +
>  ;; Constants for creating unspecs
>  (define_c_enum "unspec"
>    [UNSPEC_VSX_CONCAT
> @@ -369,6 +385,12 @@ (define_c_enum "unspec"
>     UNSPEC_REPLACE_UN
>     UNSPEC_VDIVES
>     UNSPEC_VDIVEU
> +   UNSPEC_XXEVAL
> +   UNSPEC_XXSPLTIW
> +   UNSPEC_XXSPLTID
> +   UNSPEC_XXSPLTI32DX
> +   UNSPEC_XXBLEND
> +   UNSPEC_XXPERMX
>    ])
> 
>  (define_int_iterator XVCVBF16	[UNSPEC_VSX_XVCVSPBF16
> @@ -6216,3 +6238,185 @@ (define_insn "mulv2di3"
>    "TARGET_POWER10"
>    "vmulld %0,%1,%2"
>    [(set_attr "type" "veccomplex")])
> +
> +;; XXSPLTIW built-in function support


I like the comment adds, here and below..


> +(define_insn "xxspltiw_v4si"
> +  [(set (match_operand:V4SI 0 "register_operand" "=wa")
> +	(unspec:V4SI [(match_operand:SI 1 "s32bit_cint_operand" "n")]
> +		     UNSPEC_XXSPLTIW))]
> + "TARGET_POWER10"
> + "xxspltiw %x0,%1"
> + [(set_attr "type" "vecsimple")
> +  (set_attr "prefixed" "yes")])
> +
> +(define_expand "xxspltiw_v4sf"
> +  [(set (match_operand:V4SF 0 "register_operand" "=wa")
> +	(unspec:V4SF [(match_operand:SF 1 "const_double_operand" "n")]
> +		     UNSPEC_XXSPLTIW))]
> + "TARGET_POWER10"
> +{
> +  long long value = rs6000_const_f32_to_i32 (operands[1]);
> +  emit_insn (gen_xxspltiw_v4sf_inst (operands[0], GEN_INT (value)));
> +  DONE;
> +})
> +
> +(define_insn "xxspltiw_v4sf_inst"
> +  [(set (match_operand:V4SF 0 "register_operand" "=wa")
> +	(unspec:V4SF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
> +		     UNSPEC_XXSPLTIW))]
> + "TARGET_POWER10"
> + "xxspltiw %x0,%1"
> + [(set_attr "type" "vecsimple")
> +  (set_attr "prefixed" "yes")])
> +
> +;; XXSPLTIDP built-in function support
> +(define_expand "xxspltidp_v2df"
> +  [(set (match_operand:V2DF 0 "register_operand" )
> +	(unspec:V2DF [(match_operand:SF 1 "const_double_operand")]
> +		     UNSPEC_XXSPLTID))]
> + "TARGET_POWER10"
> +{
> +  long value = rs6000_const_f32_to_i32 (operands[1]);
> +  rs6000_emit_xxspltidp_v2df (operands[0], value);
> +  DONE;
> +})
> +
> +(define_insn "xxspltidp_v2df_inst"
> +  [(set (match_operand:V2DF 0 "register_operand" "=wa")
> +	(unspec:V2DF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
> +		     UNSPEC_XXSPLTID))]
> +  "TARGET_POWER10"
> +  "xxspltidp %x0,%1"
> +  [(set_attr "type" "vecsimple")
> +   (set_attr "prefixed" "yes")])
> +
> +;; XXSPLTI32DX built-in function support
> +(define_expand "xxsplti32dx_v4si"
> +  [(set (match_operand:V4SI 0 "register_operand" "=wa")
> +	(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
> +		      (match_operand:QI 2 "u1bit_cint_operand" "n")
> +		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
> +		     UNSPEC_XXSPLTI32DX))]
> + "TARGET_POWER10"
> +{
> +  int index = INTVAL (operands[2]);
> +
> +  if (!BYTES_BIG_ENDIAN)
> +    index = 1 - index;
> +
> +   emit_insn (gen_xxsplti32dx_v4si_inst (operands[0], operands[1],
> +					 GEN_INT (index), operands[3]));
> +   DONE;
> +}
> + [(set_attr "type" "vecsimple")])
> +
> +(define_insn "xxsplti32dx_v4si_inst"
> +  [(set (match_operand:V4SI 0 "register_operand" "=wa")
> +	(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
> +		      (match_operand:QI 2 "u1bit_cint_operand" "n")
> +		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
> +		     UNSPEC_XXSPLTI32DX))]
> +  "TARGET_POWER10"
> +  "xxsplti32dx %x0,%2,%3"
> +  [(set_attr "type" "vecsimple")
> +   (set_attr "prefixed" "yes")])
> +
> +(define_expand "xxsplti32dx_v4sf"
> +  [(set (match_operand:V4SF 0 "register_operand" "=wa")
> +	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
> +		      (match_operand:QI 2 "u1bit_cint_operand" "n")
> +		      (match_operand:SF 3 "const_double_operand" "n")]
> +		     UNSPEC_XXSPLTI32DX))]
> +  "TARGET_POWER10"
> +{
> +  int index = INTVAL (operands[2]);
> +  long value = rs6000_const_f32_to_i32 (operands[3]);
> +  if (!BYTES_BIG_ENDIAN)
> +    index = 1 - index;
> +
> +   emit_insn (gen_xxsplti32dx_v4sf_inst (operands[0], operands[1],
> +					 GEN_INT (index), GEN_INT (value)));
> +   DONE;
> +})
> +
> +(define_insn "xxsplti32dx_v4sf_inst"
> +  [(set (match_operand:V4SF 0 "register_operand" "=wa")
> +	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
> +		      (match_operand:QI 2 "u1bit_cint_operand" "n")
> +		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
> +		     UNSPEC_XXSPLTI32DX))]
> +  "TARGET_POWER10"
> +  "xxsplti32dx %x0,%2,%3"
> +  [(set_attr "type" "vecsimple")
> +   (set_attr "prefixed" "yes")])
> +
> +(define_insn "xxblend_<mode>"
> +  [(set (match_operand:VM3 0 "register_operand" "=wa")
> +	(unspec:VM3 [(match_operand:VM3 1 "register_operand" "wa")
> +		     (match_operand:VM3 2 "register_operand" "wa")
> +		     (match_operand:VM3 3 "register_operand" "wa")]
> +		    UNSPEC_XXBLEND))]
> +  "TARGET_POWER10"
> +  "xxblendv<VM3_char> %x0,%x1,%x2,%x3"
> +  [(set_attr "type" "vecsimple")
> +   (set_attr "prefixed" "yes")])
> +
> +;; XXPERMX built-in function support
> +(define_expand "xxpermx"
> +  [(set (match_operand:V2DI 0 "register_operand" "+wa")
> +	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "wa")
> +		      (match_operand:V2DI 2 "register_operand" "wa")
> +		      (match_operand:V16QI 3 "register_operand" "wa")
> +		      (match_operand:QI 4 "u8bit_cint_operand" "n")]
> +		     UNSPEC_XXPERMX))]
> +  "TARGET_POWER10"
> +{
> +  if (BYTES_BIG_ENDIAN)
> +    emit_insn (gen_xxpermx_inst (operands[0], operands[1],
> +				 operands[2], operands[3],
> +				 operands[4]));
> +  else
> +    {
> +      /* Reverse value of byte element indexes by XORing with 0xFF.
> +	 Reverse the 32-byte section identifier match by subracting bits [0:2]
> +	 of elemet from 7.  */


element   (typo also existed in original).

> +      int value = INTVAL (operands[4]);
> +      rtx vreg = gen_reg_rtx (V16QImode);
> +
> +      emit_insn (gen_xxspltib_v16qi (vreg, GEN_INT (-1)));
> +      emit_insn (gen_xorv16qi3 (operands[3], operands[3], vreg));
> +      value = 7 - value;
> +      emit_insn (gen_xxpermx_inst (operands[0], operands[2],
> +				   operands[1], operands[3],
> +				   GEN_INT (value)));
> +    }
> +
> +  DONE;
> +}
> +  [(set_attr "type" "vecsimple")])
> +
> +(define_insn "xxpermx_inst"
> +  [(set (match_operand:V2DI 0 "register_operand" "+v")
> +	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v")
> +		      (match_operand:V2DI 2 "register_operand" "v")
> +		      (match_operand:V16QI 3 "register_operand" "v")
> +		      (match_operand:QI 4 "u3bit_cint_operand" "n")]
> +		     UNSPEC_XXPERMX))]
> +  "TARGET_POWER10"
> +  "xxpermx %x0,%x1,%x2,%x3,%4"
> +  [(set_attr "type" "vecsimple")
> +   (set_attr "prefixed" "yes")])
> +
> +;; XXEVAL built-in function support
> +(define_insn "xxeval"
> +  [(set (match_operand:V2DI 0 "register_operand" "=wa")
> +	(unspec:V2DI [(match_operand:V2DI 1 "altivec_register_operand" "wa")
> +		      (match_operand:V2DI 2 "altivec_register_operand" "wa")
> +		      (match_operand:V2DI 3 "altivec_register_operand" "wa")
> +		      (match_operand:QI 4 "u8bit_cint_operand" "n")]
> +		     UNSPEC_XXEVAL))]
> +   "TARGET_POWER10"
> +   "xxeval %0,%1,%2,%3,%4"
> +   [(set_attr "type" "vecsimple")
> +    (set_attr "prefixed" "yes")])
> +

thanks,
-Will

> -- 
> 2.31.1
>
Michael Meissner May 21, 2021, 1:52 a.m. UTC | #2
On Thu, May 20, 2021 at 02:30:24PM -0500, will schmidt wrote:
> > +;; XXPERMX built-in function support
> > +(define_expand "xxpermx"
> > +  [(set (match_operand:V2DI 0 "register_operand" "+wa")
> > +	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "wa")
> > +		      (match_operand:V2DI 2 "register_operand" "wa")
> > +		      (match_operand:V16QI 3 "register_operand" "wa")
> > +		      (match_operand:QI 4 "u8bit_cint_operand" "n")]
> > +		     UNSPEC_XXPERMX))]
> > +  "TARGET_POWER10"
> > +{
> > +  if (BYTES_BIG_ENDIAN)
> > +    emit_insn (gen_xxpermx_inst (operands[0], operands[1],
> > +				 operands[2], operands[3],
> > +				 operands[4]));
> > +  else
> > +    {
> > +      /* Reverse value of byte element indexes by XORing with 0xFF.
> > +	 Reverse the 32-byte section identifier match by subracting bits [0:2]
> > +	 of elemet from 7.  */
> 
> 
> element   (typo also existed in original).

Yep.  I just copied the text verbatim from altivec.md.
Michael Meissner May 24, 2021, 3:58 p.m. UTC | #3
Ping patch.  This patch is a set of 2 patches.  The second patch will need this
patch applied.  In addition, the next 3 patches that I will be submitting (to
add support for generating XXSPLTIW, XXSPLTIDP, and XXSPLTI32DX) will need this
patch applied (or else I would just have to reformulate the patch if this is
rejected).

| Date: Tue, 18 May 2021 16:46:47 -0400
| Subject: [PATCH 1/2] Move xx* builtins to vsx.md.
| Message-ID: <20210518204647.GA16671@ibm-toto.the-meissners.org>
diff mbox series

Patch

diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 1351dafbc41..8a9f55c561b 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -171,16 +171,10 @@  (define_c_enum "unspec"
    UNSPEC_VPEXTD
    UNSPEC_VCLRLB
    UNSPEC_VCLRRB
-   UNSPEC_XXEVAL
    UNSPEC_VSTRIR
    UNSPEC_VSTRIL
    UNSPEC_SLDB
    UNSPEC_SRDB
-   UNSPEC_XXSPLTIW
-   UNSPEC_XXSPLTID
-   UNSPEC_XXSPLTI32DX
-   UNSPEC_XXBLEND
-   UNSPEC_XXPERMX
 ])
 
 (define_c_enum "unspecv"
@@ -221,21 +215,6 @@  (define_mode_iterator VM2 [V4SI
 			   (KF "FLOAT128_VECTOR_P (KFmode)")
 			   (TF "FLOAT128_VECTOR_P (TFmode)")])
 
-;; Like VM2, just do char, short, int, long, float and double
-(define_mode_iterator VM3 [V4SI
-			   V8HI
-			   V16QI
-			   V4SF
-			   V2DF
-			   V2DI])
-
-(define_mode_attr VM3_char [(V2DI "d")
-			   (V4SI "w")
-			   (V8HI "h")
-			   (V16QI "b")
-			   (V2DF  "d")
-			   (V4SF  "w")])
-
 ;; Map the Vector convert single precision to double precision for integer
 ;; versus floating point
 (define_mode_attr VS_sxwsp [(V4SI "sxw") (V4SF "sp")])
@@ -820,169 +799,6 @@  (define_insn "vs<SLDB_lr>db_<mode>"
   "vs<SLDB_lr>dbi %0,%1,%2,%3"
   [(set_attr "type" "vecsimple")])
 
-(define_insn "xxspltiw_v4si"
-  [(set (match_operand:V4SI 0 "register_operand" "=wa")
-	(unspec:V4SI [(match_operand:SI 1 "s32bit_cint_operand" "n")]
-		     UNSPEC_XXSPLTIW))]
- "TARGET_POWER10"
- "xxspltiw %x0,%1"
- [(set_attr "type" "vecsimple")
-  (set_attr "prefixed" "yes")])
-
-(define_expand "xxspltiw_v4sf"
-  [(set (match_operand:V4SF 0 "register_operand" "=wa")
-	(unspec:V4SF [(match_operand:SF 1 "const_double_operand" "n")]
-		     UNSPEC_XXSPLTIW))]
- "TARGET_POWER10"
-{
-  long long value = rs6000_const_f32_to_i32 (operands[1]);
-  emit_insn (gen_xxspltiw_v4sf_inst (operands[0], GEN_INT (value)));
-  DONE;
-})
-
-(define_insn "xxspltiw_v4sf_inst"
-  [(set (match_operand:V4SF 0 "register_operand" "=wa")
-	(unspec:V4SF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
-		     UNSPEC_XXSPLTIW))]
- "TARGET_POWER10"
- "xxspltiw %x0,%1"
- [(set_attr "type" "vecsimple")
-  (set_attr "prefixed" "yes")])
-
-(define_expand "xxspltidp_v2df"
-  [(set (match_operand:V2DF 0 "register_operand" )
-	(unspec:V2DF [(match_operand:SF 1 "const_double_operand")]
-		     UNSPEC_XXSPLTID))]
- "TARGET_POWER10"
-{
-  long value = rs6000_const_f32_to_i32 (operands[1]);
-  rs6000_emit_xxspltidp_v2df (operands[0], value);
-  DONE;
-})
-
-(define_insn "xxspltidp_v2df_inst"
-  [(set (match_operand:V2DF 0 "register_operand" "=wa")
-	(unspec:V2DF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
-		     UNSPEC_XXSPLTID))]
-  "TARGET_POWER10"
-  "xxspltidp %x0,%1"
-  [(set_attr "type" "vecsimple")
-   (set_attr "prefixed" "yes")])
-
-(define_expand "xxsplti32dx_v4si"
-  [(set (match_operand:V4SI 0 "register_operand" "=wa")
-	(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
-		      (match_operand:QI 2 "u1bit_cint_operand" "n")
-		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
-		     UNSPEC_XXSPLTI32DX))]
- "TARGET_POWER10"
-{
-  int index = INTVAL (operands[2]);
-
-  if (!BYTES_BIG_ENDIAN)
-    index = 1 - index;
-
-   emit_insn (gen_xxsplti32dx_v4si_inst (operands[0], operands[1],
-					 GEN_INT (index), operands[3]));
-   DONE;
-}
- [(set_attr "type" "vecsimple")])
-
-(define_insn "xxsplti32dx_v4si_inst"
-  [(set (match_operand:V4SI 0 "register_operand" "=wa")
-	(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
-		      (match_operand:QI 2 "u1bit_cint_operand" "n")
-		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
-		     UNSPEC_XXSPLTI32DX))]
-  "TARGET_POWER10"
-  "xxsplti32dx %x0,%2,%3"
-  [(set_attr "type" "vecsimple")
-   (set_attr "prefixed" "yes")])
-
-(define_expand "xxsplti32dx_v4sf"
-  [(set (match_operand:V4SF 0 "register_operand" "=wa")
-	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
-		      (match_operand:QI 2 "u1bit_cint_operand" "n")
-		      (match_operand:SF 3 "const_double_operand" "n")]
-		     UNSPEC_XXSPLTI32DX))]
-  "TARGET_POWER10"
-{
-  int index = INTVAL (operands[2]);
-  long value = rs6000_const_f32_to_i32 (operands[3]);
-  if (!BYTES_BIG_ENDIAN)
-    index = 1 - index;
-
-   emit_insn (gen_xxsplti32dx_v4sf_inst (operands[0], operands[1],
-					 GEN_INT (index), GEN_INT (value)));
-   DONE;
-})
-
-(define_insn "xxsplti32dx_v4sf_inst"
-  [(set (match_operand:V4SF 0 "register_operand" "=wa")
-	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
-		      (match_operand:QI 2 "u1bit_cint_operand" "n")
-		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
-		     UNSPEC_XXSPLTI32DX))]
-  "TARGET_POWER10"
-  "xxsplti32dx %x0,%2,%3"
-  [(set_attr "type" "vecsimple")
-   (set_attr "prefixed" "yes")])
-
-(define_insn "xxblend_<mode>"
-  [(set (match_operand:VM3 0 "register_operand" "=wa")
-	(unspec:VM3 [(match_operand:VM3 1 "register_operand" "wa")
-		     (match_operand:VM3 2 "register_operand" "wa")
-		     (match_operand:VM3 3 "register_operand" "wa")]
-		    UNSPEC_XXBLEND))]
-  "TARGET_POWER10"
-  "xxblendv<VM3_char> %x0,%x1,%x2,%x3"
-  [(set_attr "type" "vecsimple")
-   (set_attr "prefixed" "yes")])
-
-(define_expand "xxpermx"
-  [(set (match_operand:V2DI 0 "register_operand" "+wa")
-	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "wa")
-		      (match_operand:V2DI 2 "register_operand" "wa")
-		      (match_operand:V16QI 3 "register_operand" "wa")
-		      (match_operand:QI 4 "u8bit_cint_operand" "n")]
-		     UNSPEC_XXPERMX))]
-  "TARGET_POWER10"
-{
-  if (BYTES_BIG_ENDIAN)
-    emit_insn (gen_xxpermx_inst (operands[0], operands[1],
-				 operands[2], operands[3],
-				 operands[4]));
-  else
-    {
-      /* Reverse value of byte element indexes by XORing with 0xFF.
-	 Reverse the 32-byte section identifier match by subracting bits [0:2]
-	 of elemet from 7.  */
-      int value = INTVAL (operands[4]);
-      rtx vreg = gen_reg_rtx (V16QImode);
-
-      emit_insn (gen_xxspltib_v16qi (vreg, GEN_INT (-1)));
-      emit_insn (gen_xorv16qi3 (operands[3], operands[3], vreg));
-      value = 7 - value;
-      emit_insn (gen_xxpermx_inst (operands[0], operands[2],
-				   operands[1], operands[3],
-				   GEN_INT (value)));
-    }
-
-  DONE;
-}
-  [(set_attr "type" "vecsimple")])
-
-(define_insn "xxpermx_inst"
-  [(set (match_operand:V2DI 0 "register_operand" "+v")
-	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v")
-		      (match_operand:V2DI 2 "register_operand" "v")
-		      (match_operand:V16QI 3 "register_operand" "v")
-		      (match_operand:QI 4 "u3bit_cint_operand" "n")]
-		     UNSPEC_XXPERMX))]
-  "TARGET_POWER10"
-  "xxpermx %x0,%x1,%x2,%x3,%4"
-  [(set_attr "type" "vecsimple")
-   (set_attr "prefixed" "yes")])
 
 (define_expand "vstrir_<mode>"
   [(set (match_operand:VIshort 0 "altivec_register_operand")
@@ -3621,18 +3437,6 @@  (define_insn "vperm_v16qiv8hi"
   [(set_attr "type" "vecperm")
    (set_attr "isa" "p9v,*")])
 
-(define_insn "xxeval"
-  [(set (match_operand:V2DI 0 "register_operand" "=wa")
-	(unspec:V2DI [(match_operand:V2DI 1 "altivec_register_operand" "wa")
-		      (match_operand:V2DI 2 "altivec_register_operand" "wa")
-		      (match_operand:V2DI 3 "altivec_register_operand" "wa")
-		      (match_operand:QI 4 "u8bit_cint_operand" "n")]
-		     UNSPEC_XXEVAL))]
-   "TARGET_POWER10"
-   "xxeval %0,%1,%2,%3,%4"
-   [(set_attr "type" "vecsimple")
-    (set_attr "prefixed" "yes")])
-
 (define_expand "vec_unpacku_hi_v16qi"
   [(set (match_operand:V8HI 0 "register_operand" "=v")
         (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")]
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index bcb92be2f5c..a859038d399 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -271,6 +271,22 @@  (define_mode_iterator VSX_MM4 [V16QI V8HI V4SI V2DI])
 ;; and Vector Integer Multiply/Divide/Modulo Instructions
 (define_mode_iterator VIlong [V2DI V4SI])
 
+;; Like VM2 in altivec.md, just do char, short, int, long, float and double
+(define_mode_iterator VM3 [V4SI
+			   V8HI
+			   V16QI
+			   V4SF
+			   V2DF
+			   V2DI])
+
+(define_mode_attr VM3_char [(V2DI "d")
+			   (V4SI  "w")
+			   (V8HI  "h")
+			   (V16QI "b")
+			   (V2DF  "d")
+			   (V4SF  "w")])
+
+
 ;; Constants for creating unspecs
 (define_c_enum "unspec"
   [UNSPEC_VSX_CONCAT
@@ -369,6 +385,12 @@  (define_c_enum "unspec"
    UNSPEC_REPLACE_UN
    UNSPEC_VDIVES
    UNSPEC_VDIVEU
+   UNSPEC_XXEVAL
+   UNSPEC_XXSPLTIW
+   UNSPEC_XXSPLTID
+   UNSPEC_XXSPLTI32DX
+   UNSPEC_XXBLEND
+   UNSPEC_XXPERMX
   ])
 
 (define_int_iterator XVCVBF16	[UNSPEC_VSX_XVCVSPBF16
@@ -6216,3 +6238,185 @@  (define_insn "mulv2di3"
   "TARGET_POWER10"
   "vmulld %0,%1,%2"
   [(set_attr "type" "veccomplex")])
+
+;; XXSPLTIW built-in function support
+(define_insn "xxspltiw_v4si"
+  [(set (match_operand:V4SI 0 "register_operand" "=wa")
+	(unspec:V4SI [(match_operand:SI 1 "s32bit_cint_operand" "n")]
+		     UNSPEC_XXSPLTIW))]
+ "TARGET_POWER10"
+ "xxspltiw %x0,%1"
+ [(set_attr "type" "vecsimple")
+  (set_attr "prefixed" "yes")])
+
+(define_expand "xxspltiw_v4sf"
+  [(set (match_operand:V4SF 0 "register_operand" "=wa")
+	(unspec:V4SF [(match_operand:SF 1 "const_double_operand" "n")]
+		     UNSPEC_XXSPLTIW))]
+ "TARGET_POWER10"
+{
+  long long value = rs6000_const_f32_to_i32 (operands[1]);
+  emit_insn (gen_xxspltiw_v4sf_inst (operands[0], GEN_INT (value)));
+  DONE;
+})
+
+(define_insn "xxspltiw_v4sf_inst"
+  [(set (match_operand:V4SF 0 "register_operand" "=wa")
+	(unspec:V4SF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
+		     UNSPEC_XXSPLTIW))]
+ "TARGET_POWER10"
+ "xxspltiw %x0,%1"
+ [(set_attr "type" "vecsimple")
+  (set_attr "prefixed" "yes")])
+
+;; XXSPLTIDP built-in function support
+(define_expand "xxspltidp_v2df"
+  [(set (match_operand:V2DF 0 "register_operand" )
+	(unspec:V2DF [(match_operand:SF 1 "const_double_operand")]
+		     UNSPEC_XXSPLTID))]
+ "TARGET_POWER10"
+{
+  long value = rs6000_const_f32_to_i32 (operands[1]);
+  rs6000_emit_xxspltidp_v2df (operands[0], value);
+  DONE;
+})
+
+(define_insn "xxspltidp_v2df_inst"
+  [(set (match_operand:V2DF 0 "register_operand" "=wa")
+	(unspec:V2DF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
+		     UNSPEC_XXSPLTID))]
+  "TARGET_POWER10"
+  "xxspltidp %x0,%1"
+  [(set_attr "type" "vecsimple")
+   (set_attr "prefixed" "yes")])
+
+;; XXSPLTI32DX built-in function support
+(define_expand "xxsplti32dx_v4si"
+  [(set (match_operand:V4SI 0 "register_operand" "=wa")
+	(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
+		      (match_operand:QI 2 "u1bit_cint_operand" "n")
+		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
+		     UNSPEC_XXSPLTI32DX))]
+ "TARGET_POWER10"
+{
+  int index = INTVAL (operands[2]);
+
+  if (!BYTES_BIG_ENDIAN)
+    index = 1 - index;
+
+   emit_insn (gen_xxsplti32dx_v4si_inst (operands[0], operands[1],
+					 GEN_INT (index), operands[3]));
+   DONE;
+}
+ [(set_attr "type" "vecsimple")])
+
+(define_insn "xxsplti32dx_v4si_inst"
+  [(set (match_operand:V4SI 0 "register_operand" "=wa")
+	(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
+		      (match_operand:QI 2 "u1bit_cint_operand" "n")
+		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
+		     UNSPEC_XXSPLTI32DX))]
+  "TARGET_POWER10"
+  "xxsplti32dx %x0,%2,%3"
+  [(set_attr "type" "vecsimple")
+   (set_attr "prefixed" "yes")])
+
+(define_expand "xxsplti32dx_v4sf"
+  [(set (match_operand:V4SF 0 "register_operand" "=wa")
+	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
+		      (match_operand:QI 2 "u1bit_cint_operand" "n")
+		      (match_operand:SF 3 "const_double_operand" "n")]
+		     UNSPEC_XXSPLTI32DX))]
+  "TARGET_POWER10"
+{
+  int index = INTVAL (operands[2]);
+  long value = rs6000_const_f32_to_i32 (operands[3]);
+  if (!BYTES_BIG_ENDIAN)
+    index = 1 - index;
+
+   emit_insn (gen_xxsplti32dx_v4sf_inst (operands[0], operands[1],
+					 GEN_INT (index), GEN_INT (value)));
+   DONE;
+})
+
+(define_insn "xxsplti32dx_v4sf_inst"
+  [(set (match_operand:V4SF 0 "register_operand" "=wa")
+	(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
+		      (match_operand:QI 2 "u1bit_cint_operand" "n")
+		      (match_operand:SI 3 "s32bit_cint_operand" "n")]
+		     UNSPEC_XXSPLTI32DX))]
+  "TARGET_POWER10"
+  "xxsplti32dx %x0,%2,%3"
+  [(set_attr "type" "vecsimple")
+   (set_attr "prefixed" "yes")])
+
+(define_insn "xxblend_<mode>"
+  [(set (match_operand:VM3 0 "register_operand" "=wa")
+	(unspec:VM3 [(match_operand:VM3 1 "register_operand" "wa")
+		     (match_operand:VM3 2 "register_operand" "wa")
+		     (match_operand:VM3 3 "register_operand" "wa")]
+		    UNSPEC_XXBLEND))]
+  "TARGET_POWER10"
+  "xxblendv<VM3_char> %x0,%x1,%x2,%x3"
+  [(set_attr "type" "vecsimple")
+   (set_attr "prefixed" "yes")])
+
+;; XXPERMX built-in function support
+(define_expand "xxpermx"
+  [(set (match_operand:V2DI 0 "register_operand" "+wa")
+	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "wa")
+		      (match_operand:V2DI 2 "register_operand" "wa")
+		      (match_operand:V16QI 3 "register_operand" "wa")
+		      (match_operand:QI 4 "u8bit_cint_operand" "n")]
+		     UNSPEC_XXPERMX))]
+  "TARGET_POWER10"
+{
+  if (BYTES_BIG_ENDIAN)
+    emit_insn (gen_xxpermx_inst (operands[0], operands[1],
+				 operands[2], operands[3],
+				 operands[4]));
+  else
+    {
+      /* Reverse value of byte element indexes by XORing with 0xFF.
+	 Reverse the 32-byte section identifier match by subracting bits [0:2]
+	 of elemet from 7.  */
+      int value = INTVAL (operands[4]);
+      rtx vreg = gen_reg_rtx (V16QImode);
+
+      emit_insn (gen_xxspltib_v16qi (vreg, GEN_INT (-1)));
+      emit_insn (gen_xorv16qi3 (operands[3], operands[3], vreg));
+      value = 7 - value;
+      emit_insn (gen_xxpermx_inst (operands[0], operands[2],
+				   operands[1], operands[3],
+				   GEN_INT (value)));
+    }
+
+  DONE;
+}
+  [(set_attr "type" "vecsimple")])
+
+(define_insn "xxpermx_inst"
+  [(set (match_operand:V2DI 0 "register_operand" "+v")
+	(unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v")
+		      (match_operand:V2DI 2 "register_operand" "v")
+		      (match_operand:V16QI 3 "register_operand" "v")
+		      (match_operand:QI 4 "u3bit_cint_operand" "n")]
+		     UNSPEC_XXPERMX))]
+  "TARGET_POWER10"
+  "xxpermx %x0,%x1,%x2,%x3,%4"
+  [(set_attr "type" "vecsimple")
+   (set_attr "prefixed" "yes")])
+
+;; XXEVAL built-in function support
+(define_insn "xxeval"
+  [(set (match_operand:V2DI 0 "register_operand" "=wa")
+	(unspec:V2DI [(match_operand:V2DI 1 "altivec_register_operand" "wa")
+		      (match_operand:V2DI 2 "altivec_register_operand" "wa")
+		      (match_operand:V2DI 3 "altivec_register_operand" "wa")
+		      (match_operand:QI 4 "u8bit_cint_operand" "n")]
+		     UNSPEC_XXEVAL))]
+   "TARGET_POWER10"
+   "xxeval %0,%1,%2,%3,%4"
+   [(set_attr "type" "vecsimple")
+    (set_attr "prefixed" "yes")])
+