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 <meiss...@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 > >