https://gcc.gnu.org/g:95aabf6c1c2292cadce7c3a4c1bbe3fbfdc6972b

commit 95aabf6c1c2292cadce7c3a4c1bbe3fbfdc6972b
Author: Michael Meissner <[email protected]>
Date:   Thu Oct 9 02:30:44 2025 -0400

    Implement __bfloat16 pack and unpack; Implement _Float16 unpack.
    
    2025-10-09  Michael Meissner  <[email protected]>
    
    gcc/
    
            * config/rs6000/float16.md (UNSPEC_XVCVSPHP_V8HF): New unspec.
            (UNSPEC_XVCVSPBF16_V8BF): Likewise.
            (vec_pack_trunc_v4sf): New insns.
            (xvcvsphp_v8hf): Likewise.
            (xvcvspbf16_v8bf): Likewise.
            (vec_unpacks_hi_v8hf): Likewise.
            (vec_unpacks_lo_v8hf): Likewise.
            (xvcvhpsp_v8hf): Likewise.
            (vec_unpacks_hi_v8bf): Likewise.
            (vec_unpacks_lo_v8bf): Likewise.
            (xvcvbf16spn_v8bf): Likewise.
            * config/rs6000/vector.md (vec_pack_trunc_v4sf): Delete here, 
create new
            function in float16.md that packs __bfloat16 instead of _Float16.
            (vec_unpacks_hi_v8hf): Move to float16.md.
            * config/rs6000/vsx.md (vsx_xvcvsphp_v8hf): Delete.

Diff:
---
 gcc/config/rs6000/float16.md | 166 ++++++++++++++++++++++++++++++++++++++++++-
 gcc/config/rs6000/vector.md  |  27 -------
 gcc/config/rs6000/vsx.md     |   9 ---
 3 files changed, 164 insertions(+), 38 deletions(-)

diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md
index 91a0c4f00ccf..543fb4f87f36 100644
--- a/gcc/config/rs6000/float16.md
+++ b/gcc/config/rs6000/float16.md
@@ -67,7 +67,9 @@
   [UNSPEC_FP16_SHIFT_LEFT_32BIT
    UNSPEC_CVT_FP16_TO_V4SF
    UNSPEC_XXSPLTW_FP16
-   UNSPEC_XVCVSPBF16_BF])
+   UNSPEC_XVCVSPBF16_BF
+   UNSPEC_XVCVSPHP_V8HF
+   UNSPEC_XVCVSPBF16_V8BF])
 
 
 ;; _Float16 and __bfloat16 moves
@@ -661,7 +663,7 @@
                   UNSPEC_XVCVSPBF16_BF))]
   "TARGET_BFLOAT16_HW"
   "xvcvspbf16 %x0,%x1"
-  [(set_attr "type" "vecperm")])
+  [(set_attr "type" "vecfloat")])
 
 
 ;; Negate 16-bit floating point by XOR with -0.0.  We only do this on
@@ -787,3 +789,163 @@
    xxlor %x0,%x1,%x2
    or %0,%1,%2"
   [(set_attr "type" "veclogical,integer")])
+
+
+;; 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;
+;; })
+
+(define_expand "vec_pack_trunc_v4sf"
+  [(match_operand:V8BF 0 "vfloat_operand")
+   (match_operand:V4SF 1 "vfloat_operand")
+   (match_operand:V4SF 2 "vfloat_operand")]
+  "TARGET_BFLOAT16_HW"
+{
+  rtx r1 = gen_reg_rtx (V8BFmode);
+  rtx r2 = gen_reg_rtx (V8BFmode);
+
+  emit_insn (gen_xvcvspbf16_v8bf (r1, operands[1]));
+  emit_insn (gen_xvcvspbf16_v8bf (r2, operands[2]));
+  rs6000_expand_extract_even (operands[0], r1, r2);
+  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")
+       (unspec:V8HF [(match_operand:V4SF 1 "vsx_register_operand" "wa")]
+                    UNSPEC_XVCVSPHP_V8HF))]
+  "TARGET_P9_VECTOR"
+  "xvcvsphp %x0,%x1"
+[(set_attr "type" "vecfloat")])
+
+;; Used for vector conversion to __bloat16
+(define_insn "xvcvspbf16_v8bf"
+  [(set (match_operand:V8BF 0 "vsx_register_operand" "=wa")
+       (unspec:V8BF [(match_operand:V4SF 1 "vsx_register_operand" "wa")]
+                    UNSPEC_XVCVSPBF16_V8BF))]
+  "TARGET_BFLOAT16_HW"
+  "xvcvspbf16 %x0,%x1"
+  [(set_attr "type" "vecfloat")])
+
+;; Vector unpack support.  Given the name is for the type being
+;; unpacked, we can unpack both __bfloat16 and _Float16.
+
+;; Unpack vector _Float16
+(define_expand "vec_unpacks_hi_v8hf"
+  [(match_operand:V4SF 0 "vfloat_operand")
+   (match_operand:V8HF 1 "vfloat_operand")]
+  "TARGET_FLOAT16_HW"
+{
+  rtx reg = gen_reg_rtx (V8HFmode);
+
+  rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN);
+  emit_insn (gen_xvcvhpsp_v8hf (operands[0], reg));
+  DONE;
+})
+
+(define_expand "vec_unpacks_lo_v8hf"
+  [(match_operand:V4SF 0 "vfloat_operand")
+   (match_operand:V8HF 1 "vfloat_operand")]
+  "TARGET_FLOAT16_HW"
+{
+  rtx reg = gen_reg_rtx (V8HFmode);
+
+  rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN);
+  emit_insn (gen_xvcvhpsp_v8hf (operands[0], reg));
+  DONE;
+})
+
+;; Used for vector conversion from __bfloat16
+(define_insn "xvcvhpsp_v8hf"
+  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
+       (unspec:V4SF [(match_operand:V8HF 1 "vsx_register_operand" "wa")]
+                    UNSPEC_CVT_FP16_TO_V4SF))]
+  "TARGET_BFLOAT16_HW"
+  "xvcvhpsp %x0,%x1"
+  [(set_attr "type" "vecperm")])
+
+;; Unpack vector __bfloat16
+(define_expand "vec_unpacks_hi_v8bf"
+  [(match_operand:V4SF 0 "vfloat_operand")
+   (match_operand:V8BF 1 "vfloat_operand")]
+  "TARGET_BFLOAT16_HW"
+{
+  rtx reg = gen_reg_rtx (V8BFmode);
+
+  rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN);
+  emit_insn (gen_xvcvbf16spn_v8bf (operands[0], reg));
+  DONE;
+})
+
+(define_expand "vec_unpacks_lo_v8bf"
+  [(match_operand:V4SF 0 "vfloat_operand")
+   (match_operand:V8BF 1 "vfloat_operand")]
+  "TARGET_BFLOAT16_HW"
+{
+  rtx reg = gen_reg_rtx (V8BFmode);
+
+  rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN);
+  emit_insn (gen_xvcvbf16spn_v8bf (operands[0], reg));
+  DONE;
+})
+
+;; Used for vector conversion from __bfloat16
+(define_insn "xvcvbf16spn_v8bf"
+  [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa")
+       (unspec:V4SF [(match_operand:V8BF 1 "vsx_register_operand" "wa")]
+                    UNSPEC_CVT_FP16_TO_V4SF))]
+  "TARGET_BFLOAT16_HW"
+  "xvcvbf16spn %x0,%x1"
+  [(set_attr "type" "vecperm")])
diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md
index 883cc3dbf516..0b9727cca35c 100644
--- a/gcc/config/rs6000/vector.md
+++ b/gcc/config/rs6000/vector.md
@@ -1222,21 +1222,6 @@
   DONE;
 })
 
-(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"
-{
-  rtx r1 = gen_reg_rtx (V8HFmode);
-  rtx r2 = gen_reg_rtx (V8HFmode);
-
-  emit_insn (gen_vsx_xvcvsphp_v8hf (r1, operands[1]));
-  emit_insn (gen_vsx_xvcvsphp_v8hf (r2, operands[2]));
-  rs6000_expand_extract_even (operands[0], r1, r2);
-  DONE;
-})
-
 ;; Convert single word types to double word
 (define_expand "vec_unpacks_hi_v4sf"
   [(match_operand:V2DF 0 "vfloat_operand")
@@ -1310,18 +1295,6 @@
   DONE;
 })
 
-(define_expand "vec_unpacks_hi_v8hf"
-  [(match_operand:V4SF 0 "vfloat_operand")
-   (match_operand:V8HF 1 "vfloat_operand")]
-  "TARGET_FLOAT16"
-{
-  rtx reg = gen_reg_rtx (V8HFmode);
-
-  rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN);
-  emit_insn (gen_vsx_xvcvhpsp (operands[0], reg));
-  DONE;
-})
-
 
 ;; Align vector loads with a permute.
 (define_expand "vec_realign_load_<mode>"
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 18d14a1dc477..0bbf80055fa1 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -2472,15 +2472,6 @@
   "xvcvsphp %x0,%x1"
 [(set_attr "type" "vecfloat")])
 
-;; Used for conversion to/from _Float16
-(define_insn "vsx_xvcvsphp_v8hf"
-  [(set (match_operand:V8HF 0 "register_operand" "=wa")
-       (unspec:V8HF [(match_operand:V4SF 1 "vsx_register_operand" "wa")]
-                    UNSPEC_VSX_XVCVSPHP))]
-  "TARGET_P9_VECTOR"
-  "xvcvsphp %x0,%x1"
-[(set_attr "type" "vecfloat")])
-
 ;; xscvdpsp used for splat'ing a scalar to V4SF, knowing that the internal SF
 ;; format of scalars is actually DF.
 (define_insn "vsx_xscvdpsp_scalar"

Reply via email to