diff mbox series

[5/5] Add Power10 XXSPLTIDP for SFmode/DFmode constants.

Message ID YYSu6FMxMQyhRD3d@toto.the-meissners.org
State New
Headers show
Series Add Power10 XXSPLTI* and LXVKQ instructions | expand

Commit Message

Michael Meissner Nov. 5, 2021, 4:11 a.m. UTC
Generate XXSPLTIDP for scalars on power10.

This patch implements XXSPLTIDP support for SF, and DF scalar constants.
The previous patch added support for vector constants.  This patch adds
the support for SFmode and DFmode scalar constants.

I added 2 new tests to test loading up SF and DF scalar constants.

2021-11-05  Michael Meissner  <meissner@the-meissners.org>

gcc/

	* config/rs6000/rs6000.md (UNSPEC_XXSPLTIDP_CONST): New unspec.
	(UNSPEC_XXSPLTIW_CONST): New unspec.
	(movsf_hardfloat): Add support for generating XXSPLTIDP.
	(mov<mode>_hardfloat32): Likewise.
	(mov<mode>_hardfloat64): Likewise.
	(xxspltidp_<mode>_internal): New insns.
	(xxspltiw_<mode>_internal): New insns.
	(splitters for SF/DFmode): Add new splitters for XXSPLTIDP.

gcc/testsuite/

	* gcc.target/powerpc/vec-splat-constant-df.c: New test.
	* gcc.target/powerpc/vec-splat-constant-sf.c: New test.
---
 gcc/config/rs6000/rs6000.md                   | 97 +++++++++++++++----
 .../powerpc/vec-splat-constant-df.c           | 60 ++++++++++++
 .../powerpc/vec-splat-constant-sf.c           | 60 ++++++++++++
 3 files changed, 199 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c

Comments

will schmidt Nov. 5, 2021, 7:38 p.m. UTC | #1
On Fri, 2021-11-05 at 00:11 -0400, Michael Meissner wrote:
> Generate XXSPLTIDP for scalars on power10.
> 
> This patch implements XXSPLTIDP support for SF, and DF scalar constants.
> The previous patch added support for vector constants.  This patch adds
> the support for SFmode and DFmode scalar constants.
> 
> I added 2 new tests to test loading up SF and DF scalar constants.


ok

> 
> 2021-11-05  Michael Meissner  <meissner@the-meissners.org>
> 
> gcc/
> 
> 	* config/rs6000/rs6000.md (UNSPEC_XXSPLTIDP_CONST): New unspec.
> 	(UNSPEC_XXSPLTIW_CONST): New unspec.
> 	(movsf_hardfloat): Add support for generating XXSPLTIDP.
> 	(mov<mode>_hardfloat32): Likewise.
> 	(mov<mode>_hardfloat64): Likewise.
> 	(xxspltidp_<mode>_internal): New insns.
> 	(xxspltiw_<mode>_internal): New insns.
> 	(splitters for SF/DFmode): Add new splitters for XXSPLTIDP.
> 
> gcc/testsuite/
> 
> 	* gcc.target/powerpc/vec-splat-constant-df.c: New test.
> 	* gcc.target/powerpc/vec-splat-constant-sf.c: New test.
> ---

ok


>  gcc/config/rs6000/rs6000.md                   | 97 +++++++++++++++----
>  .../powerpc/vec-splat-constant-df.c           | 60 ++++++++++++
>  .../powerpc/vec-splat-constant-sf.c           | 60 ++++++++++++
>  3 files changed, 199 insertions(+), 18 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
>  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
> 
> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
> index 3a7bcd2426e..4122acb98cf 100644
> --- a/gcc/config/rs6000/rs6000.md
> +++ b/gcc/config/rs6000/rs6000.md
> @@ -156,6 +156,8 @@ (define_c_enum "unspec"
>     UNSPEC_PEXTD
>     UNSPEC_HASHST
>     UNSPEC_HASHCHK
> +   UNSPEC_XXSPLTIDP_CONST
> +   UNSPEC_XXSPLTIW_CONST
>    ])
> 
>  ;;
> @@ -7764,17 +7766,17 @@ (define_split
>  ;;
>  ;;	LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
>  ;;	STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
> -;;	MR           MT<x>      MF<x>       NOP
> +;;	MR           MT<x>      MF<x>       NOP        XXSPLTIDP
> 
>  (define_insn "movsf_hardfloat"
>    [(set (match_operand:SF 0 "nonimmediate_operand"
>  	 "=!r,       f,         v,          wa,        m,         wY,
>  	  Z,         m,         wa,         !r,        f,         wa,
> -	  !r,        *c*l,      !r,         *h")
> +	  !r,        *c*l,      !r,         *h,        wa")
>  	(match_operand:SF 1 "input_operand"
>  	 "m,         m,         wY,         Z,         f,         v,
>  	  wa,        r,         j,          j,         f,         wa,
> -	  r,         r,         *h,         0"))]
> +	  r,         r,         *h,         0,         eP"))]
>    "(register_operand (operands[0], SFmode)
>     || register_operand (operands[1], SFmode))
>     && TARGET_HARD_FLOAT
> @@ -7796,15 +7798,16 @@ (define_insn "movsf_hardfloat"
>     mr %0,%1
>     mt%0 %1
>     mf%1 %0
> -   nop"
> +   nop
> +   #"
>    [(set_attr "type"
>  	"load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
>  	 fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
> -	 *,          mtjmpr,    mfjmpr,     *")
> +	 *,          mtjmpr,    mfjmpr,     *,         vecperm")
>     (set_attr "isa"
>  	"*,          *,         p9v,        p8v,       *,         p9v,
>  	 p8v,        *,         *,          *,         *,         *,
> -	 *,          *,         *,          *")])
> +	 *,          *,         *,          *,         p10")])
> 
>  ;;	LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
>  ;;	FMR          MR         MT%0       MF%1       NOP
> @@ -8064,18 +8067,18 @@ (define_split
> 
>  ;;           STFD         LFD         FMR         LXSD        STXSD
>  ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
> -;;           LWZ          STW         MR
> +;;           LWZ          STW         MR          XXSPLTIDP
> 
> 
>  (define_insn "*mov<mode>_hardfloat32"
>    [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
>              "=m,          d,          d,          <f64_p9>,   wY,
>                <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
> -              Y,          r,          !r")
> +              Y,          r,          !r,         wa")
>  	(match_operand:FMOVE64 1 "input_operand"
>               "d,          m,          d,          wY,         <f64_p9>,
>                Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
> -              r,          Y,          r"))]
> +              r,          Y,          r,          eP"))]
>    "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
>     && (gpc_reg_operand (operands[0], <MODE>mode)
>         || gpc_reg_operand (operands[1], <MODE>mode))"
> @@ -8092,20 +8095,21 @@ (define_insn "*mov<mode>_hardfloat32"
>     #
>     #
>     #
> +   #
>     #"
>    [(set_attr "type"
>              "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
>               fpload,      fpstore,    veclogical, veclogical, two,
> -             store,       load,       two")
> +             store,       load,       two,        vecperm")
>     (set_attr "size" "64")
>     (set_attr "length"
>              "*,           *,          *,          *,          *,
>               *,           *,          *,          *,          8,
> -             8,           8,          8")
> +             8,           8,          8,          *")
>     (set_attr "isa"
>              "*,           *,          *,          p9v,        p9v,
>               p7v,         p7v,        *,          *,          *,
> -             *,           *,          *")])
> +             *,           *,          *,          p10")])
> 
>  ;;           STW      LWZ     MR      G-const H-const F-const
> 
> @@ -8132,19 +8136,19 @@ (define_insn "*mov<mode>_softfloat32"
>  ;;           STFD         LFD         FMR         LXSD        STXSD
>  ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
>  ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
> -;;           NOP          MFVSRD      MTVSRD
> +;;           NOP          MFVSRD      MTVSRD      XXSPLTIDP
> 
>  (define_insn "*mov<mode>_hardfloat64"
>    [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
>             "=m,           d,          d,          <f64_p9>,   wY,
>               <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
>               YZ,          r,          !r,         *c*l,       !r,
> -            *h,           r,          <f64_dm>")
> +            *h,           r,          <f64_dm>,   wa")
>  	(match_operand:FMOVE64 1 "input_operand"
>              "d,           m,          d,          wY,         <f64_p9>,
>               Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
>               r,           YZ,         r,          r,          *h,
> -             0,           <f64_dm>,   r"))]
> +             0,           <f64_dm>,   r,          eP"))]
>    "TARGET_POWERPC64 && TARGET_HARD_FLOAT
>     && (gpc_reg_operand (operands[0], <MODE>mode)
>         || gpc_reg_operand (operands[1], <MODE>mode))"
> @@ -8166,18 +8170,19 @@ (define_insn "*mov<mode>_hardfloat64"
>     mf%1 %0
>     nop
>     mfvsrd %0,%x1
> -   mtvsrd %x0,%1"
> +   mtvsrd %x0,%1
> +   #"
>    [(set_attr "type"
>              "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
>               fpload,      fpstore,    veclogical, veclogical, integer,
>               store,       load,       *,          mtjmpr,     mfjmpr,
> -             *,           mfvsr,      mtvsr")
> +             *,           mfvsr,      mtvsr,      vecperm")
>     (set_attr "size" "64")
>     (set_attr "isa"
>              "*,           *,          *,          p9v,        p9v,
>               p7v,         p7v,        *,          *,          *,
>               *,           *,          *,          *,          *,
> -             *,           p8v,        p8v")])
> +             *,           p8v,        p8v,        p10")])
> 
>  ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
>  ;;           H-const  F-const  Special
> @@ -8211,6 +8216,62 @@ (define_insn "*mov<mode>_softfloat64"
>     (set_attr "length"
>              "*,       *,      *,      *,      *,      8,
>               12,      16,     *")])
> +

ok


> +;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
> +;; constants that look like DFmode floating point values where both elements
> +;; are the same.  The constant has to be expressible as a SFmode constant that
> +;; is not a SFmode denormal value.
> +;;
> +;; We don't need splitters for the 128-bit types, since the function
> +;; rs6000_output_move_128bit handles the generation of XXSPLTIDP.

ok

> +(define_insn "xxspltidp_<mode>_internal"
> +  [(set (match_operand:SFDF 0 "register_operand" "=wa")
> +	(unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
> +		     UNSPEC_XXSPLTIDP_CONST))]
> +  "TARGET_POWER10"
> +  "xxspltidp %x0,%1"
> +  [(set_attr "type" "vecperm")
> +   (set_attr "prefixed" "yes")])
> +
> +(define_insn "xxspltiw_<mode>_internal"
> +  [(set (match_operand:SFDF 0 "register_operand" "=wa")
> +	(unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
> +		     UNSPEC_XXSPLTIW_CONST))]
> +  "TARGET_POWER10"
> +  "xxspltiw %x0,%1"
> +  [(set_attr "type" "vecperm")
> +   (set_attr "prefixed" "yes")])
> +
> +(define_split
> +  [(set (match_operand:SFDF 0 "vsx_register_operand")
> +	(match_operand:SFDF 1 "vsx_prefixed_constant"))]
> +  "TARGET_POWER10"
> +  [(pc)]
> +{
> +  rtx dest = operands[0];
> +  rtx src = operands[1];
> +  vec_const_128bit_type vsx_const;
> +
> +  if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const))
> +    gcc_unreachable ();
> +
> +  unsigned imm = constant_generates_xxspltidp (&vsx_const);
> +  if (imm)
> +    {
> +      emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm)));
> +      DONE;
> +    }
> +
> +  imm = constant_generates_xxspltiw (&vsx_const);
> +  if (imm)
> +    {
> +      emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm)));
> +      DONE;
> +    }
> +
> +  else
> +    gcc_unreachable ();
> +})


ok
Nothing further, 
thanks,
-Will


>  
>  (define_expand "mov<mode>"
>    [(set (match_operand:FMOVE128 0 "general_operand")
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
> new file mode 100644
> index 00000000000..8f6e176f9af
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
> @@ -0,0 +1,60 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target power10_ok } */
> +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
> +
> +#include <math.h>
> +
> +/* Test generating DFmode constants with the ISA 3.1 (power10) XXSPLTIDP
> +   instruction.  */
> +
> +double
> +scalar_double_0 (void)
> +{
> +  return 0.0;			/* XXSPLTIB or XXLXOR.  */
> +}
> +
> +double
> +scalar_double_1 (void)
> +{
> +  return 1.0;			/* XXSPLTIDP.  */
> +}
> +
> +#ifndef __FAST_MATH__
> +double
> +scalar_double_m0 (void)
> +{
> +  return -0.0;			/* XXSPLTIDP.  */
> +}
> +
> +double
> +scalar_double_nan (void)
> +{
> +  return __builtin_nan ("");	/* XXSPLTIDP.  */
> +}
> +
> +double
> +scalar_double_inf (void)
> +{
> +  return __builtin_inf ();	/* XXSPLTIDP.  */
> +}
> +
> +double
> +scalar_double_m_inf (void)	/* XXSPLTIDP.  */
> +{
> +  return - __builtin_inf ();
> +}
> +#endif
> +
> +double
> +scalar_double_pi (void)
> +{
> +  return M_PI;			/* PLFD.  */
> +}
> +
> +double
> +scalar_double_denorm (void)
> +{
> +  return 0x1p-149f;		/* PLFD.  */
> +}
> +
> +/* { dg-final { scan-assembler-times {\mxxspltidp\M} 5 } } */
> diff --git a/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
> new file mode 100644
> index 00000000000..72504bdfbbd
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
> @@ -0,0 +1,60 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target power10_ok } */
> +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
> +
> +#include <math.h>
> +
> +/* Test generating SFmode constants with the ISA 3.1 (power10) XXSPLTIDP
> +   instruction.  */
> +
> +float
> +scalar_float_0 (void)
> +{
> +  return 0.0f;			/* XXSPLTIB or XXLXOR.  */
> +}
> +
> +float
> +scalar_float_1 (void)
> +{
> +  return 1.0f;			/* XXSPLTIDP.  */
> +}
> +
> +#ifndef __FAST_MATH__
> +float
> +scalar_float_m0 (void)
> +{
> +  return -0.0f;			/* XXSPLTIDP.  */
> +}
> +
> +float
> +scalar_float_nan (void)
> +{
> +  return __builtin_nanf ("");	/* XXSPLTIDP.  */
> +}
> +
> +float
> +scalar_float_inf (void)
> +{
> +  return __builtin_inff ();	/* XXSPLTIDP.  */
> +}
> +
> +float
> +scalar_float_m_inf (void)	/* XXSPLTIDP.  */
> +{
> +  return - __builtin_inff ();
> +}
> +#endif
> +
> +float
> +scalar_float_pi (void)
> +{
> +  return (float)M_PI;		/* XXSPLTIDP.  */
> +}
> +
> +float
> +scalar_float_denorm (void)
> +{
> +  return 0x1p-149f;		/* PLFS.  */
> +}
> +
> +/* { dg-final { scan-assembler-times {\mxxspltidp\M} 6 } } */
> -- 
> 2.31.1
> 
>
Michael Meissner Nov. 15, 2021, 4:38 p.m. UTC | #2
Ping patch.

| Date: Fri, 5 Nov 2021 00:11:20 -0400
| Subject: [PATCH 5/5] Add Power10 XXSPLTIDP for SFmode/DFmode constants.
| Message-ID: <YYSu6FMxMQyhRD3d@toto.the-meissners.org>
Michael Meissner Dec. 13, 2021, 5:07 p.m. UTC | #3
Ping patch #2.

| Date: Fri, 5 Nov 2021 00:11:20 -0400
| From: Michael Meissner <meissner@linux.ibm.com>
| Subject: [PATCH 5/5] Add Power10 XXSPLTIDP for SFmode/DFmode constants.
| Message-ID: <YYSu6FMxMQyhRD3d@toto.the-meissners.org>

https://gcc.gnu.org/pipermail/gcc-patches/2021-November/583394.html

Note, I will be on-line through December 20th.  I will be off-line December
21st through January 1st.
David Edelsohn Dec. 14, 2021, 5:01 p.m. UTC | #4
On Fri, Nov 5, 2021 at 3:38 PM will schmidt <will_schmidt@vnet.ibm.com> wrote:
>
> On Fri, 2021-11-05 at 00:11 -0400, Michael Meissner wrote:
> > Generate XXSPLTIDP for scalars on power10.
> >
> > This patch implements XXSPLTIDP support for SF, and DF scalar constants.
> > The previous patch added support for vector constants.  This patch adds
> > the support for SFmode and DFmode scalar constants.
> >
> > I added 2 new tests to test loading up SF and DF scalar constants.
>
>
> ok
>
> >
> > 2021-11-05  Michael Meissner  <meissner@the-meissners.org>
> >
> > gcc/
> >
> >       * config/rs6000/rs6000.md (UNSPEC_XXSPLTIDP_CONST): New unspec.
> >       (UNSPEC_XXSPLTIW_CONST): New unspec.
> >       (movsf_hardfloat): Add support for generating XXSPLTIDP.
> >       (mov<mode>_hardfloat32): Likewise.
> >       (mov<mode>_hardfloat64): Likewise.
> >       (xxspltidp_<mode>_internal): New insns.
> >       (xxspltiw_<mode>_internal): New insns.
> >       (splitters for SF/DFmode): Add new splitters for XXSPLTIDP.
> >
> > gcc/testsuite/
> >
> >       * gcc.target/powerpc/vec-splat-constant-df.c: New test.
> >       * gcc.target/powerpc/vec-splat-constant-sf.c: New test.
> > ---
>
> ok
>
>
> >  gcc/config/rs6000/rs6000.md                   | 97 +++++++++++++++----
> >  .../powerpc/vec-splat-constant-df.c           | 60 ++++++++++++
> >  .../powerpc/vec-splat-constant-sf.c           | 60 ++++++++++++
> >  3 files changed, 199 insertions(+), 18 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
> >  create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
> >
> > diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
> > index 3a7bcd2426e..4122acb98cf 100644
> > --- a/gcc/config/rs6000/rs6000.md
> > +++ b/gcc/config/rs6000/rs6000.md
> > @@ -156,6 +156,8 @@ (define_c_enum "unspec"
> >     UNSPEC_PEXTD
> >     UNSPEC_HASHST
> >     UNSPEC_HASHCHK
> > +   UNSPEC_XXSPLTIDP_CONST
> > +   UNSPEC_XXSPLTIW_CONST
> >    ])
> >
> >  ;;
> > @@ -7764,17 +7766,17 @@ (define_split
> >  ;;
> >  ;;   LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
> >  ;;   STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
> > -;;   MR           MT<x>      MF<x>       NOP
> > +;;   MR           MT<x>      MF<x>       NOP        XXSPLTIDP
> >
> >  (define_insn "movsf_hardfloat"
> >    [(set (match_operand:SF 0 "nonimmediate_operand"
> >        "=!r,       f,         v,          wa,        m,         wY,
> >         Z,         m,         wa,         !r,        f,         wa,
> > -       !r,        *c*l,      !r,         *h")
> > +       !r,        *c*l,      !r,         *h,        wa")
> >       (match_operand:SF 1 "input_operand"
> >        "m,         m,         wY,         Z,         f,         v,
> >         wa,        r,         j,          j,         f,         wa,
> > -       r,         r,         *h,         0"))]
> > +       r,         r,         *h,         0,         eP"))]
> >    "(register_operand (operands[0], SFmode)
> >     || register_operand (operands[1], SFmode))
> >     && TARGET_HARD_FLOAT
> > @@ -7796,15 +7798,16 @@ (define_insn "movsf_hardfloat"
> >     mr %0,%1
> >     mt%0 %1
> >     mf%1 %0
> > -   nop"
> > +   nop
> > +   #"
> >    [(set_attr "type"
> >       "load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
> >        fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
> > -      *,          mtjmpr,    mfjmpr,     *")
> > +      *,          mtjmpr,    mfjmpr,     *,         vecperm")
> >     (set_attr "isa"
> >       "*,          *,         p9v,        p8v,       *,         p9v,
> >        p8v,        *,         *,          *,         *,         *,
> > -      *,          *,         *,          *")])
> > +      *,          *,         *,          *,         p10")])
> >
> >  ;;   LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
> >  ;;   FMR          MR         MT%0       MF%1       NOP
> > @@ -8064,18 +8067,18 @@ (define_split
> >
> >  ;;           STFD         LFD         FMR         LXSD        STXSD
> >  ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
> > -;;           LWZ          STW         MR
> > +;;           LWZ          STW         MR          XXSPLTIDP
> >
> >
> >  (define_insn "*mov<mode>_hardfloat32"
> >    [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
> >              "=m,          d,          d,          <f64_p9>,   wY,
> >                <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
> > -              Y,          r,          !r")
> > +              Y,          r,          !r,         wa")
> >       (match_operand:FMOVE64 1 "input_operand"
> >               "d,          m,          d,          wY,         <f64_p9>,
> >                Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
> > -              r,          Y,          r"))]
> > +              r,          Y,          r,          eP"))]
> >    "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
> >     && (gpc_reg_operand (operands[0], <MODE>mode)
> >         || gpc_reg_operand (operands[1], <MODE>mode))"
> > @@ -8092,20 +8095,21 @@ (define_insn "*mov<mode>_hardfloat32"
> >     #
> >     #
> >     #
> > +   #
> >     #"
> >    [(set_attr "type"
> >              "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
> >               fpload,      fpstore,    veclogical, veclogical, two,
> > -             store,       load,       two")
> > +             store,       load,       two,        vecperm")
> >     (set_attr "size" "64")
> >     (set_attr "length"
> >              "*,           *,          *,          *,          *,
> >               *,           *,          *,          *,          8,
> > -             8,           8,          8")
> > +             8,           8,          8,          *")
> >     (set_attr "isa"
> >              "*,           *,          *,          p9v,        p9v,
> >               p7v,         p7v,        *,          *,          *,
> > -             *,           *,          *")])
> > +             *,           *,          *,          p10")])
> >
> >  ;;           STW      LWZ     MR      G-const H-const F-const
> >
> > @@ -8132,19 +8136,19 @@ (define_insn "*mov<mode>_softfloat32"
> >  ;;           STFD         LFD         FMR         LXSD        STXSD
> >  ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
> >  ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
> > -;;           NOP          MFVSRD      MTVSRD
> > +;;           NOP          MFVSRD      MTVSRD      XXSPLTIDP
> >
> >  (define_insn "*mov<mode>_hardfloat64"
> >    [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
> >             "=m,           d,          d,          <f64_p9>,   wY,
> >               <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
> >               YZ,          r,          !r,         *c*l,       !r,
> > -            *h,           r,          <f64_dm>")
> > +            *h,           r,          <f64_dm>,   wa")
> >       (match_operand:FMOVE64 1 "input_operand"
> >              "d,           m,          d,          wY,         <f64_p9>,
> >               Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
> >               r,           YZ,         r,          r,          *h,
> > -             0,           <f64_dm>,   r"))]
> > +             0,           <f64_dm>,   r,          eP"))]
> >    "TARGET_POWERPC64 && TARGET_HARD_FLOAT
> >     && (gpc_reg_operand (operands[0], <MODE>mode)
> >         || gpc_reg_operand (operands[1], <MODE>mode))"
> > @@ -8166,18 +8170,19 @@ (define_insn "*mov<mode>_hardfloat64"
> >     mf%1 %0
> >     nop
> >     mfvsrd %0,%x1
> > -   mtvsrd %x0,%1"
> > +   mtvsrd %x0,%1
> > +   #"
> >    [(set_attr "type"
> >              "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
> >               fpload,      fpstore,    veclogical, veclogical, integer,
> >               store,       load,       *,          mtjmpr,     mfjmpr,
> > -             *,           mfvsr,      mtvsr")
> > +             *,           mfvsr,      mtvsr,      vecperm")
> >     (set_attr "size" "64")
> >     (set_attr "isa"
> >              "*,           *,          *,          p9v,        p9v,
> >               p7v,         p7v,        *,          *,          *,
> >               *,           *,          *,          *,          *,
> > -             *,           p8v,        p8v")])
> > +             *,           p8v,        p8v,        p10")])
> >
> >  ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
> >  ;;           H-const  F-const  Special
> > @@ -8211,6 +8216,62 @@ (define_insn "*mov<mode>_softfloat64"
> >     (set_attr "length"
> >              "*,       *,      *,      *,      *,      8,
> >               12,      16,     *")])
> > +
>
> ok
>
>
> > +;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
> > +;; constants that look like DFmode floating point values where both elements
> > +;; are the same.  The constant has to be expressible as a SFmode constant that
> > +;; is not a SFmode denormal value.
> > +;;
> > +;; We don't need splitters for the 128-bit types, since the function
> > +;; rs6000_output_move_128bit handles the generation of XXSPLTIDP.
>
> ok
>
> > +(define_insn "xxspltidp_<mode>_internal"
> > +  [(set (match_operand:SFDF 0 "register_operand" "=wa")
> > +     (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
> > +                  UNSPEC_XXSPLTIDP_CONST))]
> > +  "TARGET_POWER10"
> > +  "xxspltidp %x0,%1"
> > +  [(set_attr "type" "vecperm")
> > +   (set_attr "prefixed" "yes")])
> > +
> > +(define_insn "xxspltiw_<mode>_internal"
> > +  [(set (match_operand:SFDF 0 "register_operand" "=wa")
> > +     (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
> > +                  UNSPEC_XXSPLTIW_CONST))]
> > +  "TARGET_POWER10"
> > +  "xxspltiw %x0,%1"
> > +  [(set_attr "type" "vecperm")
> > +   (set_attr "prefixed" "yes")])
> > +
> > +(define_split
> > +  [(set (match_operand:SFDF 0 "vsx_register_operand")
> > +     (match_operand:SFDF 1 "vsx_prefixed_constant"))]
> > +  "TARGET_POWER10"
> > +  [(pc)]
> > +{
> > +  rtx dest = operands[0];
> > +  rtx src = operands[1];
> > +  vec_const_128bit_type vsx_const;
> > +
> > +  if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const))
> > +    gcc_unreachable ();
> > +
> > +  unsigned imm = constant_generates_xxspltidp (&vsx_const);
> > +  if (imm)
> > +    {
> > +      emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm)));
> > +      DONE;
> > +    }
> > +
> > +  imm = constant_generates_xxspltiw (&vsx_const);
> > +  if (imm)
> > +    {
> > +      emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm)));
> > +      DONE;
> > +    }
> > +
> > +  else
> > +    gcc_unreachable ();
> > +})
>
>
> ok
> Nothing further,
> thanks,
> -Will

Okay.

Thanks, David
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 3a7bcd2426e..4122acb98cf 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -156,6 +156,8 @@  (define_c_enum "unspec"
    UNSPEC_PEXTD
    UNSPEC_HASHST
    UNSPEC_HASHCHK
+   UNSPEC_XXSPLTIDP_CONST
+   UNSPEC_XXSPLTIW_CONST
   ])
 
 ;;
@@ -7764,17 +7766,17 @@  (define_split
 ;;
 ;;	LWZ          LFS        LXSSP       LXSSPX     STFS       STXSSP
 ;;	STXSSPX      STW        XXLXOR      LI         FMR        XSCPSGNDP
-;;	MR           MT<x>      MF<x>       NOP
+;;	MR           MT<x>      MF<x>       NOP        XXSPLTIDP
 
 (define_insn "movsf_hardfloat"
   [(set (match_operand:SF 0 "nonimmediate_operand"
 	 "=!r,       f,         v,          wa,        m,         wY,
 	  Z,         m,         wa,         !r,        f,         wa,
-	  !r,        *c*l,      !r,         *h")
+	  !r,        *c*l,      !r,         *h,        wa")
 	(match_operand:SF 1 "input_operand"
 	 "m,         m,         wY,         Z,         f,         v,
 	  wa,        r,         j,          j,         f,         wa,
-	  r,         r,         *h,         0"))]
+	  r,         r,         *h,         0,         eP"))]
   "(register_operand (operands[0], SFmode)
    || register_operand (operands[1], SFmode))
    && TARGET_HARD_FLOAT
@@ -7796,15 +7798,16 @@  (define_insn "movsf_hardfloat"
    mr %0,%1
    mt%0 %1
    mf%1 %0
-   nop"
+   nop
+   #"
   [(set_attr "type"
 	"load,       fpload,    fpload,     fpload,    fpstore,   fpstore,
 	 fpstore,    store,     veclogical, integer,   fpsimple,  fpsimple,
-	 *,          mtjmpr,    mfjmpr,     *")
+	 *,          mtjmpr,    mfjmpr,     *,         vecperm")
    (set_attr "isa"
 	"*,          *,         p9v,        p8v,       *,         p9v,
 	 p8v,        *,         *,          *,         *,         *,
-	 *,          *,         *,          *")])
+	 *,          *,         *,          *,         p10")])
 
 ;;	LWZ          LFIWZX     STW        STFIWX     MTVSRWZ    MFVSRWZ
 ;;	FMR          MR         MT%0       MF%1       NOP
@@ -8064,18 +8067,18 @@  (define_split
 
 ;;           STFD         LFD         FMR         LXSD        STXSD
 ;;           LXSD         STXSD       XXLOR       XXLXOR      GPR<-0
-;;           LWZ          STW         MR
+;;           LWZ          STW         MR          XXSPLTIDP
 
 
 (define_insn "*mov<mode>_hardfloat32"
   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
             "=m,          d,          d,          <f64_p9>,   wY,
               <f64_av>,   Z,          <f64_vsx>,  <f64_vsx>,  !r,
-              Y,          r,          !r")
+              Y,          r,          !r,         wa")
 	(match_operand:FMOVE64 1 "input_operand"
              "d,          m,          d,          wY,         <f64_p9>,
               Z,          <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
-              r,          Y,          r"))]
+              r,          Y,          r,          eP"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
@@ -8092,20 +8095,21 @@  (define_insn "*mov<mode>_hardfloat32"
    #
    #
    #
+   #
    #"
   [(set_attr "type"
             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
              fpload,      fpstore,    veclogical, veclogical, two,
-             store,       load,       two")
+             store,       load,       two,        vecperm")
    (set_attr "size" "64")
    (set_attr "length"
             "*,           *,          *,          *,          *,
              *,           *,          *,          *,          8,
-             8,           8,          8")
+             8,           8,          8,          *")
    (set_attr "isa"
             "*,           *,          *,          p9v,        p9v,
              p7v,         p7v,        *,          *,          *,
-             *,           *,          *")])
+             *,           *,          *,          p10")])
 
 ;;           STW      LWZ     MR      G-const H-const F-const
 
@@ -8132,19 +8136,19 @@  (define_insn "*mov<mode>_softfloat32"
 ;;           STFD         LFD         FMR         LXSD        STXSD
 ;;           LXSDX        STXSDX      XXLOR       XXLXOR      LI 0
 ;;           STD          LD          MR          MT{CTR,LR}  MF{CTR,LR}
-;;           NOP          MFVSRD      MTVSRD
+;;           NOP          MFVSRD      MTVSRD      XXSPLTIDP
 
 (define_insn "*mov<mode>_hardfloat64"
   [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
            "=m,           d,          d,          <f64_p9>,   wY,
              <f64_av>,    Z,          <f64_vsx>,  <f64_vsx>,  !r,
              YZ,          r,          !r,         *c*l,       !r,
-            *h,           r,          <f64_dm>")
+            *h,           r,          <f64_dm>,   wa")
 	(match_operand:FMOVE64 1 "input_operand"
             "d,           m,          d,          wY,         <f64_p9>,
              Z,           <f64_av>,   <f64_vsx>,  <zero_fp>,  <zero_fp>,
              r,           YZ,         r,          r,          *h,
-             0,           <f64_dm>,   r"))]
+             0,           <f64_dm>,   r,          eP"))]
   "TARGET_POWERPC64 && TARGET_HARD_FLOAT
    && (gpc_reg_operand (operands[0], <MODE>mode)
        || gpc_reg_operand (operands[1], <MODE>mode))"
@@ -8166,18 +8170,19 @@  (define_insn "*mov<mode>_hardfloat64"
    mf%1 %0
    nop
    mfvsrd %0,%x1
-   mtvsrd %x0,%1"
+   mtvsrd %x0,%1
+   #"
   [(set_attr "type"
             "fpstore,     fpload,     fpsimple,   fpload,     fpstore,
              fpload,      fpstore,    veclogical, veclogical, integer,
              store,       load,       *,          mtjmpr,     mfjmpr,
-             *,           mfvsr,      mtvsr")
+             *,           mfvsr,      mtvsr,      vecperm")
    (set_attr "size" "64")
    (set_attr "isa"
             "*,           *,          *,          p9v,        p9v,
              p7v,         p7v,        *,          *,          *,
              *,           *,          *,          *,          *,
-             *,           p8v,        p8v")])
+             *,           p8v,        p8v,        p10")])
 
 ;;           STD      LD       MR      MT<SPR> MF<SPR> G-const
 ;;           H-const  F-const  Special
@@ -8211,6 +8216,62 @@  (define_insn "*mov<mode>_softfloat64"
    (set_attr "length"
             "*,       *,      *,      *,      *,      8,
              12,      16,     *")])
+
+;; Split the VSX prefixed instruction to support SFmode and DFmode scalar
+;; constants that look like DFmode floating point values where both elements
+;; are the same.  The constant has to be expressible as a SFmode constant that
+;; is not a SFmode denormal value.
+;;
+;; We don't need splitters for the 128-bit types, since the function
+;; rs6000_output_move_128bit handles the generation of XXSPLTIDP.
+(define_insn "xxspltidp_<mode>_internal"
+  [(set (match_operand:SFDF 0 "register_operand" "=wa")
+	(unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
+		     UNSPEC_XXSPLTIDP_CONST))]
+  "TARGET_POWER10"
+  "xxspltidp %x0,%1"
+  [(set_attr "type" "vecperm")
+   (set_attr "prefixed" "yes")])
+
+(define_insn "xxspltiw_<mode>_internal"
+  [(set (match_operand:SFDF 0 "register_operand" "=wa")
+	(unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")]
+		     UNSPEC_XXSPLTIW_CONST))]
+  "TARGET_POWER10"
+  "xxspltiw %x0,%1"
+  [(set_attr "type" "vecperm")
+   (set_attr "prefixed" "yes")])
+
+(define_split
+  [(set (match_operand:SFDF 0 "vsx_register_operand")
+	(match_operand:SFDF 1 "vsx_prefixed_constant"))]
+  "TARGET_POWER10"
+  [(pc)]
+{
+  rtx dest = operands[0];
+  rtx src = operands[1];
+  vec_const_128bit_type vsx_const;
+
+  if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const))
+    gcc_unreachable ();
+
+  unsigned imm = constant_generates_xxspltidp (&vsx_const);
+  if (imm)
+    {
+      emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm)));
+      DONE;
+    }
+
+  imm = constant_generates_xxspltiw (&vsx_const);
+  if (imm)
+    {
+      emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm)));
+      DONE;
+    }
+
+  else
+    gcc_unreachable ();
+})
 
 (define_expand "mov<mode>"
   [(set (match_operand:FMOVE128 0 "general_operand")
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
new file mode 100644
index 00000000000..8f6e176f9af
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c
@@ -0,0 +1,60 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+#include <math.h>
+
+/* Test generating DFmode constants with the ISA 3.1 (power10) XXSPLTIDP
+   instruction.  */
+
+double
+scalar_double_0 (void)
+{
+  return 0.0;			/* XXSPLTIB or XXLXOR.  */
+}
+
+double
+scalar_double_1 (void)
+{
+  return 1.0;			/* XXSPLTIDP.  */
+}
+
+#ifndef __FAST_MATH__
+double
+scalar_double_m0 (void)
+{
+  return -0.0;			/* XXSPLTIDP.  */
+}
+
+double
+scalar_double_nan (void)
+{
+  return __builtin_nan ("");	/* XXSPLTIDP.  */
+}
+
+double
+scalar_double_inf (void)
+{
+  return __builtin_inf ();	/* XXSPLTIDP.  */
+}
+
+double
+scalar_double_m_inf (void)	/* XXSPLTIDP.  */
+{
+  return - __builtin_inf ();
+}
+#endif
+
+double
+scalar_double_pi (void)
+{
+  return M_PI;			/* PLFD.  */
+}
+
+double
+scalar_double_denorm (void)
+{
+  return 0x1p-149f;		/* PLFD.  */
+}
+
+/* { dg-final { scan-assembler-times {\mxxspltidp\M} 5 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
new file mode 100644
index 00000000000..72504bdfbbd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c
@@ -0,0 +1,60 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2" } */
+
+#include <math.h>
+
+/* Test generating SFmode constants with the ISA 3.1 (power10) XXSPLTIDP
+   instruction.  */
+
+float
+scalar_float_0 (void)
+{
+  return 0.0f;			/* XXSPLTIB or XXLXOR.  */
+}
+
+float
+scalar_float_1 (void)
+{
+  return 1.0f;			/* XXSPLTIDP.  */
+}
+
+#ifndef __FAST_MATH__
+float
+scalar_float_m0 (void)
+{
+  return -0.0f;			/* XXSPLTIDP.  */
+}
+
+float
+scalar_float_nan (void)
+{
+  return __builtin_nanf ("");	/* XXSPLTIDP.  */
+}
+
+float
+scalar_float_inf (void)
+{
+  return __builtin_inff ();	/* XXSPLTIDP.  */
+}
+
+float
+scalar_float_m_inf (void)	/* XXSPLTIDP.  */
+{
+  return - __builtin_inff ();
+}
+#endif
+
+float
+scalar_float_pi (void)
+{
+  return (float)M_PI;		/* XXSPLTIDP.  */
+}
+
+float
+scalar_float_denorm (void)
+{
+  return 0x1p-149f;		/* PLFS.  */
+}
+
+/* { dg-final { scan-assembler-times {\mxxspltidp\M} 6 } } */