]> gcc.gnu.org Git - gcc.git/commitdiff
Generate XXSPLTIDP for scalars on power10.
authorMichael Meissner <meissner@linux.ibm.com>
Wed, 15 Dec 2021 07:30:20 +0000 (02:30 -0500)
committerMichael Meissner <meissner@linux.ibm.com>
Wed, 15 Dec 2021 07:30:20 +0000 (02:30 -0500)
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-12-15  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
gcc/testsuite/gcc.target/powerpc/vec-splat-constant-df.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vec-splat-constant-sf.c [new file with mode: 0644]

index 3a7bcd2426e7a13564e61da2069ecebce71783bd..4122acb98cfde4554ee653c503918ac81463a38d 100644 (file)
    UNSPEC_PEXTD
    UNSPEC_HASHST
    UNSPEC_HASHCHK
+   UNSPEC_XXSPLTIDP_CONST
+   UNSPEC_XXSPLTIW_CONST
   ])
 
 ;;
 ;;
 ;;     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
    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
 
 ;;           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))"
    #
    #
    #
+   #
    #"
   [(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
 
 ;;           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))"
    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
    (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 ();
+})
 \f
 (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 (file)
index 0000000..8f6e176
--- /dev/null
@@ -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 (file)
index 0000000..72504bd
--- /dev/null
@@ -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 } } */
This page took 0.094925 seconds and 5 git commands to generate.