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
