https://gcc.gnu.org/g:eb24553668ed6b292750936dd8dc85bd838d66bf

commit eb24553668ed6b292750936dd8dc85bd838d66bf
Author: Michael Meissner <[email protected]>
Date:   Tue Oct 7 23:38:53 2025 -0400

    Add power8 support for 16-bit floating point.
    
    2025-10-07  Michael Meissner  <[email protected]>
    
    gcc/
    
            * config/rs6000/float16.md (neg<mode>2): Require hardware support 
for
            the 16-bit floating point type.
            (xor<mode>3): Likewise.
            (abs<mode>2): Likewise.
            (andc<mode>3): Likewise.
            (nabs<mode>2): Likewise.
            (ior<mode>3): Likewise.
            * config/rs6000/rs6000-p8swap.cc (rs6000_gen_stvx): Add support for
            V8HFmode and V8BFmode.
            (rs6000_gen_lvx): Likewise.
            (replace_swapped_load_constant): Likewise.
            * config/rs6000/rs6000.md (rs6000_option_override_internal): Make
            -mcpu=power8 the minimum for 16-bit floating point.

Diff:
---
 gcc/config/rs6000/float16.md       | 55 +++++++++++++++++++-------------------
 gcc/config/rs6000/rs6000-p8swap.cc | 10 ++++++-
 gcc/config/rs6000/rs6000.cc        | 12 +++++----
 3 files changed, 44 insertions(+), 33 deletions(-)

diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md
index 7e06df76b05e..91a0c4f00ccf 100644
--- a/gcc/config/rs6000/float16.md
+++ b/gcc/config/rs6000/float16.md
@@ -668,17 +668,17 @@
 ;; power10, since we can easily load up -0.0 via XXSPLTIW.
 
 (define_insn_and_split "neg<mode>2"
-  [(set (match_operand:FP16 0 "register_operand" "=wa,?wr")
-       (neg:FP16 (match_operand:FP16 1 "register_operand" "wa,wr")))
-   (clobber (match_scratch:FP16 2 "=&wa,&r"))]
+  [(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"
   "#"
   "&& 1"
   [(set (match_dup 2)
        (match_dup 3))
    (set (match_dup 0)
-       (xor:FP16 (match_dup 1)
-                 (match_dup 2)))]
+       (xor:FP16_HW (match_dup 1)
+                    (match_dup 2)))]
 {
   REAL_VALUE_TYPE dconst;
 
@@ -695,9 +695,9 @@
 ;; XOR used to negate a 16-bit floating point type
 
 (define_insn "*xor<mode>3"
-  [(set (match_operand:FP16 0 "register_operand" "=wa,?wr")
-       (xor:FP16 (match_operand:FP16 1 "register_operand" "wa,wr")
-                 (match_operand:FP16 2 "register_operand" "wa,wr")))]
+  [(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"
   "@
    xxlxor %x0,%x1,%x2
@@ -707,17 +707,18 @@
 ;; 16-bit floating point absolute value
 
 (define_insn_and_split "abs<mode>2"
-  [(set (match_operand:FP16 0 "register_operand" "=wa,?wr")
-       (abs:FP16 (match_operand:FP16 1 "register_operand" "wa,wr")))
-   (clobber (match_scratch:FP16 2 "=&wa,&r"))]
+  [(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"
   "#"
   "&& 1"
   [(set (match_dup 2)
        (match_dup 3))
    (set (match_dup 0)
-       (and:FP16 (match_dup 1)
-                 (not:FP16 (match_dup 2))))]
+       (and:FP16_HW (match_dup 1)
+                    (not:FP16_HW (match_dup 2))))]
 {
   REAL_VALUE_TYPE dconst;
 
@@ -735,10 +736,10 @@
 ;; for absolute value.
 
 (define_insn "*andc<mode>3"
-  [(set (match_operand:FP16 0 "register_operand" "=wa,?wr")
-       (and:FP16 (match_operand:FP16 1 "register_operand" "wa,wr")
-                 (not:FP16
-                  (match_operand:FP16 2 "register_operand" "wa,wr"))))]
+  [(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"
   "@
    xxlandc %x0,%x1,%x2
@@ -748,19 +749,19 @@
 ;; 16-bit negative floating point absolute value
 
 (define_insn_and_split "*nabs<mode>2"
-  [(set (match_operand:FP16 0 "register_operand" "=wa,?wr")
-       (neg:FP16
-        (abs:FP16
-         (match_operand:FP16 1 "register_operand" "wa,wr"))))
-   (clobber (match_scratch:FP16 2 "=&wa,&r"))]
+  [(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"
   "#"
   "&& 1"
   [(set (match_dup 2)
        (match_dup 3))
    (set (match_dup 0)
-       (ior:FP16 (match_dup 1)
-                 (match_dup 2)))]
+       (ior:FP16_HW (match_dup 1)
+                    (match_dup 2)))]
 {
   REAL_VALUE_TYPE dconst;
 
@@ -778,9 +779,9 @@
 ;; for negative absolute value.
 
 (define_insn "*ior<mode>3"
-  [(set (match_operand:FP16 0 "register_operand" "=wa,?wr")
-       (ior:FP16 (match_operand:FP16 1 "register_operand" "wa,wr")
-                 (match_operand:FP16 2 "register_operand" "wa,wr")))]
+  [(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"
   "@
    xxlor %x0,%x1,%x2
diff --git a/gcc/config/rs6000/rs6000-p8swap.cc 
b/gcc/config/rs6000/rs6000-p8swap.cc
index 4fb107c60a47..7ba50f11a7bf 100644
--- a/gcc/config/rs6000/rs6000-p8swap.cc
+++ b/gcc/config/rs6000/rs6000-p8swap.cc
@@ -1598,6 +1598,10 @@ rs6000_gen_stvx (enum machine_mode mode, rtx dest_exp, 
rtx src_exp)
     stvx = gen_altivec_stvx_v16qi (src_exp, dest_exp);
   else if (mode == V8HImode)
     stvx = gen_altivec_stvx_v8hi (src_exp, dest_exp);
+  else if (mode == V8HFmode)
+    stvx = gen_altivec_stvx_v8hf (src_exp, dest_exp);
+  else if (mode == V8BFmode)
+    stvx = gen_altivec_stvx_v8bf (src_exp, dest_exp);
   else if (mode == V4SImode)
     stvx = gen_altivec_stvx_v4si (src_exp, dest_exp);
   else if (mode == V4SFmode)
@@ -1718,6 +1722,10 @@ rs6000_gen_lvx (enum machine_mode mode, rtx dest_exp, 
rtx src_exp)
     lvx = gen_altivec_lvx_v16qi (dest_exp, src_exp);
   else if (mode == V8HImode)
     lvx = gen_altivec_lvx_v8hi (dest_exp, src_exp);
+  else if (mode == V8HFmode)
+    lvx = gen_altivec_lvx_v8hf (dest_exp, src_exp);
+  else if (mode == V8BFmode)
+    lvx = gen_altivec_lvx_v8bf (dest_exp, src_exp);
   else if (mode == V4SImode)
     lvx = gen_altivec_lvx_v4si (dest_exp, src_exp);
   else if (mode == V4SFmode)
@@ -1922,7 +1930,7 @@ replace_swapped_load_constant (swap_web_entry 
*insn_entry, rtx swap_insn)
       rtx new_const_vector = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
       new_mem = force_const_mem (mode, new_const_vector);
     }
-  else if (mode == V8HImode)
+  else if (mode == V8HImode || mode == V8HFmode || mode == V8BFmode)
     {
       rtx vals = gen_rtx_PARALLEL (mode, rtvec_alloc (8));
       int i;
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 5c3f8d0836d9..397b37c9bbcd 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -3942,19 +3942,21 @@ rs6000_option_override_internal (bool global_init_p)
        }
     }
 
-  /* -mfloat16 and -mbfloat16 needs VSX at a minimum.  */
-  if (TARGET_FLOAT16 && !TARGET_VSX)
+  /* -mfloat16 and -mbfloat16 needs power8 at a minimum in order to load up
+      16-bit values into vector registers via loads/stores from GPRs and then
+      using direct moves.  */
+  if (TARGET_FLOAT16 && !TARGET_POWER8)
     {
       rs6000_isa_flags &= ~OPTION_MASK_FLOAT16;
       if (rs6000_isa_flags_explicit & OPTION_MASK_FLOAT16)
-       error ("%qs requires at least %qs", "-mfloat16", "-mvsx");
+       error ("%qs requires at least %qs", "-mfloat16", "-mcpu=power8");
     }
 
-  if (TARGET_BFLOAT16 && !TARGET_VSX)
+  if (TARGET_BFLOAT16 && !TARGET_POWER8)
     {
       rs6000_isa_flags &= ~OPTION_MASK_BFLOAT16;
       if (rs6000_isa_flags_explicit & OPTION_MASK_BFLOAT16)
-       error ("%qs requires at least %qs", "-mbfloat16", "-mvsx");
+       error ("%qs requires at least %qs", "-mbfloat16", "-mcpu=power8");
     }
 
   /* If hard-float/altivec/vsx were explicitly turned off then don't allow

Reply via email to