https://gcc.gnu.org/g:9e1c4fcb2e890730709b2c2ef63c7d9d79b2e777

commit 9e1c4fcb2e890730709b2c2ef63c7d9d79b2e777
Author: Michael Meissner <[email protected]>
Date:   Thu Oct 9 21:47:51 2025 -0400

    Move things around; Make unary operators work without hardware support.
    
    2025-10-09  Michael Meissner  <[email protected]>
    
    gcc/
    
            * config/rs6000/float16.md (vsx_xscvdpsp_sf): Move from vsx.md.
            (vsx_xscvdpspn_sf): Likewise.
            (neg<mode>2, FP16 iterator): Update code to not need specific 16-bit
            floating point hardware support; Add vector insns.
            (neg<mode>, VFP16 iterator): Likewise.
            (xor<mode>, FP16 iterator): Likewise.
            (xor<mode>, VFP16 iterator): Likewise.
            (abs<mode>2, FP16 iterator): Likewise.
            (abs<mode>2, VFP16 iterator): Likewise.
            (andc<mode>2, FP16 iterator): Likewise.
            (andc<mode>2, VFP16 iterator): Likewise.
            (nabs<mode>2, FP16 iterator): Likewise.
            (nabs<mode>2, VFP16 iterator): Likewise.
            (ior<mode>2, FP16 iterator): Likewise.
            (ior<mode>2, VFP16 iterator): Likewise.
            (vec_pack_trunc_v4sf_v8hf): New insn.
            (xvcvsphp_v8hf): Use vsx_register_operand instead of 
register_opernd.
            * config/rs6000/vsx.md (vsx_xscvdpsp_sf): Move to float16.md.
            (vsx_xscvdpspn_sf): Likewise.

Diff:
---
 gcc/config/rs6000/float16.md | 304 +++++++++++++++++++++++++++++--------------
 gcc/config/rs6000/vsx.md     |  18 ---
 2 files changed, 209 insertions(+), 113 deletions(-)

diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md
index 543fb4f87f36..deefd1d0c97c 100644
--- a/gcc/config/rs6000/float16.md
+++ b/gcc/config/rs6000/float16.md
@@ -193,6 +193,14 @@
   [(set_attr "type" "fpsimple")
    (set_attr "length" "12")])
 
+(define_insn "vsx_xscvdpsp_sf"
+  [(set (match_operand:V4SF 0 "vsx_register_operand" "=f,?wa")
+       (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "f,wa")]
+                             UNSPEC_VSX_CVSPDP))]
+  "VECTOR_UNIT_VSX_P (DFmode)"
+  "xscvdpsp %x0,%x1"
+  [(set_attr "type" "fp")])
+
 ;; Vector shift left by 32 bits to get the 16-bit floating point value
 ;; into the upper 32 bits for the conversion.
 (define_insn "<fp16_vector8>_shift_left_32bit"
@@ -235,6 +243,13 @@
 }
   [(set_attr "type" "fpsimple")])
 
+(define_insn "vsx_xscvdpspn_sf"
+  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
+       (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "wa")]
+                    UNSPEC_VSX_CVDPSPN))]
+  "TARGET_XSCVDPSPN"
+  "xscvdpspn %x0,%x1"
+  [(set_attr "type" "fp")])
 
 ;; Convert between HFmode/BFmode and 128-bit binary floating point and
 ;; decimal floating point types.  We use convert_move since some of the
@@ -666,151 +681,284 @@
   [(set_attr "type" "vecfloat")])
 
 
-;; Negate 16-bit floating point by XOR with -0.0.  We only do this on
-;; power10, since we can easily load up -0.0 via XXSPLTIW.
+;; Negate 16-bit floating point by XOR with -0.0.
 
 (define_insn_and_split "neg<mode>2"
-  [(set (match_operand:FP16_HW 0 "register_operand" "=wa,?wr")
-       (neg:FP16_HW (match_operand:FP16_HW 1 "register_operand" "wa,wr")))
-   (clobber (match_scratch:FP16_HW 2 "=&wa,&r"))]
-  "TARGET_POWER10 && TARGET_PREFIXED"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,?wr")
+       (neg:FP16 (match_operand:FP16 1 "gpc_reg_operand" "wa,wr")))
+   (clobber (match_scratch:FP16 2 "=&wa,&r"))]
+  ""
   "#"
   "&& 1"
   [(set (match_dup 2)
        (match_dup 3))
    (set (match_dup 0)
-       (xor:FP16_HW (match_dup 1)
-                    (match_dup 2)))]
+       (xor:FP16 (match_dup 1)
+                 (match_dup 2)))]
 {
+  if (GET_CODE (operands[2]) == SCRATCH)
+    operands[2] = gen_reg_rtx (<MODE>mode);
+
   REAL_VALUE_TYPE dconst;
 
   gcc_assert (real_from_string (&dconst, "-0.0") == 0);
 
+  rtx rc = const_double_from_real_value (dconst, <MODE>mode);
+  if (!TARGET_PREFIXED)
+    rc = force_const_mem (<MODE>mode, rc);
+
+  operands[3] = rc;
+}
+  [(set_attr "type" "veclogical,integer")
+   (set_attr "length" "16")])
+
+
+(define_insn_and_split "neg<mode>2"
+  [(set (match_operand:VFP16 0 "vsx_register_operand" "=wa")
+       (neg:VFP16 (match_operand:VFP16 1 "vsx_register_operand" "wa")))
+   (clobber (match_scratch:VFP16 2 "=&wa"))]
+  ""
+  "#"
+  "&& 1"
+  [(set (match_dup 2)
+       (match_dup 3))
+   (set (match_dup 0)
+       (xor:VFP16 (match_dup 1)
+                  (match_dup 2)))]
+{
   if (GET_CODE (operands[2]) == SCRATCH)
     operands[2] = gen_reg_rtx (<MODE>mode);
 
-  operands[3] = const_double_from_real_value (dconst, <MODE>mode);
+  REAL_VALUE_TYPE dconst;
+
+  gcc_assert (real_from_string (&dconst, "-0.0") == 0);
+  rtx nz = const_double_from_real_value (dconst, <VEC_base>mode);
+  rtvec v = gen_rtvec (8, nz, nz, nz, nz, nz, nz, nz, nz);
+  rtx vrc = gen_rtx_CONST_VECTOR (<MODE>mode, v);
+
+  if (!TARGET_PREFIXED)
+    vrc = force_const_mem (<MODE>mode, vrc);
+
+  operands[3] = vrc;
 }
-  [(set_attr "type" "veclogical,integer")
+  [(set_attr "type" "veclogical")
    (set_attr "length" "16")])
 
 ;; XOR used to negate a 16-bit floating point type
 
 (define_insn "*xor<mode>3"
-  [(set (match_operand:FP16_HW 0 "register_operand" "=wa,?wr")
-       (xor:FP16_HW (match_operand:FP16_HW 1 "register_operand" "wa,wr")
-                    (match_operand:FP16_HW 2 "register_operand" "wa,wr")))]
-  "TARGET_POWER10 && TARGET_PREFIXED"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,?wr")
+       (xor:FP16 (match_operand:FP16 1 "gpc_reg_operand" "wa,wr")
+                 (match_operand:FP16 2 "gpc_reg_operand" "wa,wr")))]
+  ""
   "@
    xxlxor %x0,%x1,%x2
    xor %0,%1,%2"
   [(set_attr "type" "veclogical,integer")])
 
+(define_insn "*xor<mode>3"
+  [(set (match_operand:VFP16 0 "vsx_register_operand" "=wa")
+       (xor:VFP16 (match_operand:VFP16 1 "vsx_register_operand" "wa")
+                  (match_operand:VFP16 2 "vsx_register_operand" "wa")))]
+  ""
+  "xxlxor %x0,%x1,%x2"
+  [(set_attr "type" "veclogical")])
+
 ;; 16-bit floating point absolute value
 
 (define_insn_and_split "abs<mode>2"
-  [(set (match_operand:FP16_HW 0 "register_operand" "=wa,?wr")
-       (abs:FP16_HW
-        (match_operand:FP16_HW 1 "register_operand" "wa,wr")))
-   (clobber (match_scratch:FP16_HW 2 "=&wa,&r"))]
-  "TARGET_POWER10 && TARGET_PREFIXED"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,?wr")
+       (abs:FP16
+        (match_operand:FP16 1 "gpc_reg_operand" "wa,wr")))
+   (clobber (match_scratch:FP16 2 "=&wa,&r"))]
+  ""
   "#"
   "&& 1"
   [(set (match_dup 2)
        (match_dup 3))
    (set (match_dup 0)
-       (and:FP16_HW (match_dup 1)
-                    (not:FP16_HW (match_dup 2))))]
+       (and:FP16 (match_dup 1)
+                 (not:FP16 (match_dup 2))))]
 {
+  if (GET_CODE (operands[2]) == SCRATCH)
+    operands[2] = gen_reg_rtx (<MODE>mode);
+
   REAL_VALUE_TYPE dconst;
 
   gcc_assert (real_from_string (&dconst, "-0.0") == 0);
 
+  rtx rc = const_double_from_real_value (dconst, <MODE>mode);
+
+  if (!TARGET_PREFIXED)
+    rc = force_const_mem (<MODE>mode, rc);
+
+  operands[3] = rc;
+}
+  [(set_attr "type" "veclogical,integer")
+   (set_attr "length" "16")])
+
+(define_insn_and_split "abs<mode>2"
+  [(set (match_operand:VFP16 0 "vsx_register_operand" "=wa")
+       (abs:VFP16
+        (match_operand:VFP16 1 "vsx_register_operand" "wa")))
+   (clobber (match_scratch:VFP16 2 "=&wa"))]
+  ""
+  "#"
+  "&& 1"
+  [(set (match_dup 2)
+       (match_dup 3))
+   (set (match_dup 0)
+       (and:VFP16 (match_dup 1)
+                  (not:VFP16 (match_dup 2))))]
+{
   if (GET_CODE (operands[2]) == SCRATCH)
     operands[2] = gen_reg_rtx (<MODE>mode);
 
-  operands[3] = const_double_from_real_value (dconst, <MODE>mode);
+  REAL_VALUE_TYPE dconst;
+
+  gcc_assert (real_from_string (&dconst, "-0.0") == 0);
+  rtx nz = const_double_from_real_value (dconst, <VEC_base>mode);
+  rtvec v = gen_rtvec (8, nz, nz, nz, nz, nz, nz, nz, nz);
+  rtx vrc = gen_rtx_CONST_VECTOR (<MODE>mode, v);
+
+  if (!TARGET_PREFIXED)
+    vrc = force_const_mem (<MODE>mode, vrc);
+
+  operands[3] = vrc;
 }
-  [(set_attr "type" "veclogical,integer")
+  [(set_attr "type" "veclogical")
    (set_attr "length" "16")])
 
 ;; ANDC used to clear the sign bit of a 16-bit floating point type
 ;; for absolute value.
 
 (define_insn "*andc<mode>3"
-  [(set (match_operand:FP16_HW 0 "register_operand" "=wa,?wr")
-       (and:FP16_HW (match_operand:FP16_HW 1 "register_operand" "wa,wr")
-                    (not:FP16_HW
-                     (match_operand:FP16_HW 2 "register_operand" "wa,wr"))))]
-  "TARGET_POWER10 && TARGET_PREFIXED"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,?wr")
+       (and:FP16 (match_operand:FP16 1 "gpc_reg_operand" "wa,wr")
+                    (not:FP16
+                     (match_operand:FP16 2 "gpc_reg_operand" "wa,wr"))))]
+  ""
   "@
    xxlandc %x0,%x1,%x2
    andc %0,%1,%2"
   [(set_attr "type" "veclogical,integer")])
 
+(define_insn "*andc<mode>3"
+  [(set (match_operand:VFP16 0 "vsx_register_operand" "=wa")
+       (and:VFP16 (match_operand:VFP16 1 "vsx_register_operand" "wa")
+                    (not:VFP16
+                     (match_operand:VFP16 2 "vsx_register_operand" "wa"))))]
+  ""
+  "xxlandc %x0,%x1,%x2"
+  [(set_attr "type" "veclogical")])
+
 ;; 16-bit negative floating point absolute value
 
 (define_insn_and_split "*nabs<mode>2"
-  [(set (match_operand:FP16_HW 0 "register_operand" "=wa,?wr")
-       (neg:FP16_HW
-        (abs:FP16_HW
-         (match_operand:FP16_HW 1 "register_operand" "wa,wr"))))
-   (clobber (match_scratch:FP16_HW 2 "=&wa,&r"))]
-  "TARGET_POWER10 && TARGET_PREFIXED"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,?wr")
+       (neg:FP16
+        (abs:FP16
+         (match_operand:FP16 1 "gpc_reg_operand" "wa,wr"))))
+   (clobber (match_scratch:FP16 2 "=&wa,&r"))]
+  ""
   "#"
   "&& 1"
   [(set (match_dup 2)
        (match_dup 3))
    (set (match_dup 0)
-       (ior:FP16_HW (match_dup 1)
-                    (match_dup 2)))]
+       (ior:FP16 (match_dup 1)
+                 (match_dup 2)))]
 {
+  if (GET_CODE (operands[2]) == SCRATCH)
+    operands[2] = gen_reg_rtx (<MODE>mode);
+
   REAL_VALUE_TYPE dconst;
 
   gcc_assert (real_from_string (&dconst, "-0.0") == 0);
+  rtx rc = const_double_from_real_value (dconst, <MODE>mode);
+
+  if (!TARGET_PREFIXED)
+    rc = force_const_mem (<MODE>mode, rc);
+
+  operands[3] = rc;
+}
+  [(set_attr "type" "veclogical,integer")
+   (set_attr "length" "16")])
 
+(define_insn_and_split "*nabs<mode>2"
+  [(set (match_operand:VFP16 0 "vsx_register_operand" "=wa")
+       (neg:VFP16
+        (abs:VFP16
+         (match_operand:VFP16 1 "vsx_register_operand" "wa"))))
+   (clobber (match_scratch:VFP16 2 "=&wa"))]
+  ""
+  "#"
+  "&& 1"
+  [(set (match_dup 2)
+       (match_dup 3))
+   (set (match_dup 0)
+       (ior:VFP16 (match_dup 1)
+                  (match_dup 2)))]
+{
   if (GET_CODE (operands[2]) == SCRATCH)
     operands[2] = gen_reg_rtx (<MODE>mode);
 
-  operands[3] = const_double_from_real_value (dconst, <MODE>mode);
+  REAL_VALUE_TYPE dconst;
+
+  gcc_assert (real_from_string (&dconst, "-0.0") == 0);
+  rtx nz = const_double_from_real_value (dconst, <VEC_base>mode);
+  rtvec v = gen_rtvec (8, nz, nz, nz, nz, nz, nz, nz, nz);
+  rtx vrc = gen_rtx_CONST_VECTOR (<MODE>mode, v);
+
+  if (!TARGET_PREFIXED)
+    vrc = force_const_mem (<MODE>mode, vrc);
+
+  operands[3] = vrc;
 }
-  [(set_attr "type" "veclogical,integer")
+  [(set_attr "type" "veclogical")
    (set_attr "length" "16")])
 
 ;; OR used to set the sign bit of a 16-bit floating point type
 ;; for negative absolute value.
 
 (define_insn "*ior<mode>3"
-  [(set (match_operand:FP16_HW 0 "register_operand" "=wa,?wr")
-       (ior:FP16_HW (match_operand:FP16_HW 1 "register_operand" "wa,wr")
-                    (match_operand:FP16_HW 2 "register_operand" "wa,wr")))]
-  "TARGET_POWER10 && TARGET_PREFIXED"
+  [(set (match_operand:FP16 0 "gpc_reg_operand" "=wa,?wr")
+       (ior:FP16 (match_operand:FP16 1 "gpc_reg_operand" "wa,wr")
+                 (match_operand:FP16 2 "gpc_reg_operand" "wa,wr")))]
+  ""
   "@
    xxlor %x0,%x1,%x2
    or %0,%1,%2"
   [(set_attr "type" "veclogical,integer")])
 
+(define_insn "*ior<mode>3"
+  [(set (match_operand:VFP16 0 "vsx_register_operand" "=wa")
+       (ior:VFP16 (match_operand:VFP16 1 "vsx_register_operand" "wa")
+                  (match_operand:VFP16 2 "vsx_register_operand" "wa")))]
+  ""
+  "xxlor %x0,%x1,%x2"
+  [(set_attr "type" "veclogical")])
 
 ;; Vector Pack support.
 
-;; Unfortunately the code assumes there is only one 16-bit floating
-;; point type.  So we have to choose whether to support packing
-;; _Float16 or __bfloat16.
-
-;; (define_expand "vec_pack_trunc_v4sf"
-;;   [(match_operand:V8HF 0 "vfloat_operand")
-;;    (match_operand:V4SF 1 "vfloat_operand")
-;;    (match_operand:V4SF 2 "vfloat_operand")]
-;;   "TARGET_FLOAT16_HW"
-;; {
-;;   rtx r1 = gen_reg_rtx (V8HFmode);
-;;   rtx r2 = gen_reg_rtx (V8HFmode);
-;; 
-;;   emit_insn (gen_xvcvsphp_v8hf (r1, operands[1]));
-;;   emit_insn (gen_xvcvsphp_v8hf (r2, operands[2]));
-;;   rs6000_expand_extract_even (operands[0], r1, r2);
-;;   DONE;
-;; })
+;; Unfortunately the machine independent code assumes there is only one
+;; 16-bit floating point type.  So we have to choose whether to support
+;; packing _Float16 or __bfloat16.
+
+(define_expand "vec_pack_trunc_v4sf_v8hf"
+  [(match_operand:V8HF 0 "vfloat_operand")
+   (match_operand:V4SF 1 "vfloat_operand")
+   (match_operand:V4SF 2 "vfloat_operand")]
+  "TARGET_FLOAT16_HW"
+{
+  rtx r1 = gen_reg_rtx (V8HFmode);
+  rtx r2 = gen_reg_rtx (V8HFmode);
+
+  emit_insn (gen_xvcvsphp_v8hf (r1, operands[1]));
+  emit_insn (gen_xvcvsphp_v8hf (r2, operands[2]));
+  rs6000_expand_extract_even (operands[0], r1, r2);
+  DONE;
+})
 
 (define_expand "vec_pack_trunc_v4sf"
   [(match_operand:V8BF 0 "vfloat_operand")
@@ -827,43 +975,9 @@
   DONE;
 })
 
-;; (define_expand "vec_pack_trunc_v4sf"
-;;   [(match_operand 0 "vfloat_operand")
-;;    (match_operand:V4SF 1 "vfloat_operand")
-;;    (match_operand:V4SF 2 "vfloat_operand")]
-;;   "TARGET_FLOAT16_HW || TARGET_BFLOAT16_HW"
-;; {
-;;   machine_mode mode = GET_MODE (operands[0]);
-;;   rtx r1, r2;
-;; 
-;;   if (mode == V8HFmode && TARGET_FLOAT16_HW)
-;;     {
-;;       r1 = gen_reg_rtx (V8HFmode);
-;;       r2 = gen_reg_rtx (V8HFmode);
-;; 
-;;       emit_insn (gen_xvcvsphp_v8hf (r1, operands[1]));
-;;       emit_insn (gen_xvcvsphp_v8hf (r2, operands[2]));
-;;     }
-;; 
-;;   else if (mode == V8BFmode && TARGET_BFLOAT16_HW)
-;;     {
-;;       r1 = gen_reg_rtx (V8BFmode);
-;;       r2 = gen_reg_rtx (V8BFmode);
-;; 
-;;       emit_insn (gen_xvcvspbf16_v8bf (r1, operands[1]));
-;;       emit_insn (gen_xvcvspbf16_v8bf (r2, operands[2]));
-;;     }
-;; 
-;;   else
-;;     FAIL;
-;; 
-;;   rs6000_expand_extract_even (operands[0], r1, r2);
-;;   DONE;
-;; })
-
 ;; Used for vector conversion to _Float16
 (define_insn "xvcvsphp_v8hf"
-  [(set (match_operand:V8HF 0 "register_operand" "=wa")
+  [(set (match_operand:V8HF 0 "vsx_register_operand" "=wa")
        (unspec:V8HF [(match_operand:V4SF 1 "vsx_register_operand" "wa")]
                     UNSPEC_XVCVSPHP_V8HF))]
   "TARGET_P9_VECTOR"
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 0bbf80055fa1..6c11d7766ed1 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -2388,14 +2388,6 @@
   "xscvdpsp %x0,%x1"
   [(set_attr "type" "fp")])
 
-(define_insn "vsx_xscvdpsp_sf"
-  [(set (match_operand:V4SF 0 "vsx_register_operand" "=f,?wa")
-       (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "f,wa")]
-                             UNSPEC_VSX_CVSPDP))]
-  "VECTOR_UNIT_VSX_P (DFmode)"
-  "xscvdpsp %x0,%x1"
-  [(set_attr "type" "fp")])
-
 (define_insn "vsx_xvcvspdp_be"
   [(set (match_operand:V2DF 0 "vsx_register_operand" "=v,?wa")
      (float_extend:V2DF
@@ -2453,7 +2445,6 @@
   [(set_attr "type" "fp")])
 
 ;; Generate xvcvhpsp instruction
-;; Used for the built-in function
 (define_insn "vsx_xvcvhpsp"
   [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
        (unspec:V4SF [(match_operand: V16QI 1 "vsx_register_operand" "wa")]
@@ -2463,7 +2454,6 @@
   [(set_attr "type" "vecfloat")])
 
 ;; Generate xvcvsphp
-;; Used for the built-in function
 (define_insn "vsx_xvcvsphp"
   [(set (match_operand:V4SI 0 "register_operand" "=wa")
        (unspec:V4SI [(match_operand:V4SF 1 "vsx_register_operand" "wa")]
@@ -2491,14 +2481,6 @@
   "xscvdpspn %x0,%x1"
   [(set_attr "type" "fp")])
 
-(define_insn "vsx_xscvdpspn_sf"
-  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
-       (unspec:V4SF [(match_operand:SF 1 "vsx_register_operand" "wa")]
-                    UNSPEC_VSX_CVDPSPN))]
-  "TARGET_XSCVDPSPN"
-  "xscvdpspn %x0,%x1"
-  [(set_attr "type" "fp")])
-
 (define_insn "vsx_xscvspdpn"
   [(set (match_operand:DF 0 "vsx_register_operand" "=wa")
        (unspec:DF [(match_operand:V4SF 1 "vsx_register_operand" "wa")]

Reply via email to