[gcc(refs/vendors/ibm/heads/gcc-16-future-float16)] Add conversions between 16-bit floating point and other scalar modes.
Michael Meissner
meissner@gcc.gnu.org
Wed Nov 12 22:46:54 GMT 2025
https://gcc.gnu.org/g:b4e7d87cf40a476e98ef1761102b3f7d01d3c5af
commit b4e7d87cf40a476e98ef1761102b3f7d01d3c5af
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Wed Nov 12 17:43:22 2025 -0500
Add conversions between 16-bit floating point and other scalar modes.
2025-11-16 Michael Meissner <meissner@linux.ibm.com>
gcc/
* config/rs6000/float16.md (fp16_float_convert): New mode iterator.
(extend<FP16_HW:mode><fp16_float_convert:mode>2): New insns to convert
between the 2 16-bit floating point modes and other floating point
scalars other than SFmode/DFmode by converting first to DFmode.
(trunc<fp16_float_convert:mode><FP16_HW:mode>2): Likewise.
(float<GPR:mode><FP16_HW:mode>2): New insns to convert beween the 2
16-bit floating point modes and signed/unsigned integers.
(floatuns<GPR:mode><FP16_HW:mode>2): Likewise.
(fix_trunc<FP16_HW:mode><GPR:mode>): Likewise.
(fixuns_trunc<FP16_HW:mode><GPR:mode>2): Likewise.
Diff:
---
gcc/config/rs6000/float16.md | 84 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/gcc/config/rs6000/float16.md b/gcc/config/rs6000/float16.md
index e27428d94864..6805cd994398 100644
--- a/gcc/config/rs6000/float16.md
+++ b/gcc/config/rs6000/float16.md
@@ -34,6 +34,10 @@
(define_mode_iterator VFP16_HW [(V8BF "TARGET_BFLOAT16_HW")
(V8HF "TARGET_FLOAT16_HW")])
+;; Mode iterator for floating point modes other than SF/DFmode that we
+;; convert to/from _Float16 (HFmode) via DFmode.
+(define_mode_iterator fp16_float_convert [TF KF IF SD DD TD])
+
;; Mode attribute giving the instruction to convert the even
;; V8HFmode or V8BFmode elements to V4SFmode
(define_mode_attr cvt_fp16_to_v4sf_insn [(BF "xvcvbf16spn")
@@ -423,3 +427,83 @@
"TARGET_BFLOAT16_HW"
"xvcvspbf16 %x0,%x1"
[(set_attr "type" "vecfloat")])
+
+;; Convert between HFmode/BFmode and 128-bit binary floating point and
+;; decimal floating point types. We use convert_move since some of the
+;; types might not have valid RTX expanders. We use DFmode as the
+;; intermediate conversion destination.
+
+(define_expand "extend<FP16_HW:mode><fp16_float_convert:mode>2"
+ [(set (match_operand:fp16_float_convert 0 "vsx_register_operand")
+ (float_extend:fp16_float_convert
+ (match_operand:FP16_HW 1 "vsx_register_operand")))]
+ ""
+{
+ rtx df_tmp = gen_reg_rtx (DFmode);
+ emit_insn (gen_extend<FP16_HW:mode>df2 (df_tmp, operands[1]));
+ convert_move (operands[0], df_tmp, 0);
+ DONE;
+})
+
+(define_expand "trunc<fp16_float_convert:mode><FP16_HW:mode>2"
+ [(set (match_operand:FP16_HW 0 "vsx_register_operand")
+ (float_truncate:FP16_HW
+ (match_operand:fp16_float_convert 1 "vsx_register_operand")))]
+ ""
+{
+ rtx df_tmp = gen_reg_rtx (DFmode);
+
+ convert_move (df_tmp, operands[1], 0);
+ emit_insn (gen_truncdf<FP16_HW:mode>2 (operands[0], df_tmp));
+ DONE;
+})
+
+;; Convert integers to 16-bit floating point modes.
+(define_expand "float<GPR:mode><FP16_HW:mode>2"
+ [(set (match_operand:FP16_HW 0 "vsx_register_operand")
+ (float:FP16_HW
+ (match_operand:GPR 1 "nonimmediate_operand")))]
+ ""
+{
+ rtx df_tmp = gen_reg_rtx (DFmode);
+ emit_insn (gen_float<GPR:mode>df2 (df_tmp, operands[1]));
+ emit_insn (gen_truncdf<FP16_HW:mode>2 (operands[0], df_tmp));
+ DONE;
+})
+
+(define_expand "floatuns<GPR:mode><FP16_HW:mode>2"
+ [(set (match_operand:FP16_HW 0 "vsx_register_operand")
+ (unsigned_float:FP16_HW
+ (match_operand:GPR 1 "nonimmediate_operand")))]
+ ""
+{
+ rtx df_tmp = gen_reg_rtx (DFmode);
+ emit_insn (gen_floatuns<GPR:mode>df2 (df_tmp, operands[1]));
+ emit_insn (gen_truncdf<FP16_HW:mode>2 (operands[0], df_tmp));
+ DONE;
+})
+
+;; Convert 16-bit floating point modes to integers
+(define_expand "fix_trunc<FP16_HW:mode><GPR:mode>2"
+ [(set (match_operand:GPR 0 "vsx_register_operand")
+ (fix:GPR
+ (match_operand:FP16_HW 1 "vsx_register_operand")))]
+ ""
+{
+ rtx df_tmp = gen_reg_rtx (DFmode);
+ emit_insn (gen_extend<FP16_HW:mode>df2 (df_tmp, operands[1]));
+ emit_insn (gen_fix_truncdf<GPR:mode>2 (operands[0], df_tmp));
+ DONE;
+})
+
+(define_expand "fixuns_trunc<FP16_HW:mode><GPR:mode>2"
+ [(set (match_operand:GPR 0 "vsx_register_operand")
+ (unsigned_fix:GPR
+ (match_operand:FP16_HW 1 "vsx_register_operand")))]
+ ""
+{
+ rtx df_tmp = gen_reg_rtx (DFmode);
+ emit_insn (gen_extend<FP16_HW:mode>df2 (df_tmp, operands[1]));
+ emit_insn (gen_fixuns_truncdf<GPR:mode>2 (operands[0], df_tmp));
+ DONE;
+})
More information about the Gcc-cvs
mailing list