Message ID | YYSu6FMxMQyhRD3d@toto.the-meissners.org |
---|---|
State | New |
Headers | show |
Series | Add Power10 XXSPLTI* and LXVKQ instructions | expand |
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 > >
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>
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.
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 --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 } } */