[gcc(refs/users/meissner/heads/work252-float)] Add conversions between 16-bit floating point and other scalar modes.

Michael Meissner via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:3449aa560d2cf01b51d9f628a66f05b484e2adf2

commit 3449aa560d2cf01b51d9f628a66f05b484e2adf2
Author: Michael Meissner <[email protected]>
Date:   Fri Jul 24 00:54:58 2026 -0400

    Add conversions between 16-bit floating point and other scalar modes.
    
    This patch adds conversions between 16-bit floating point and other scalar
    modes, by converting the first mode to double, and then converting that double
    to the second mode.
    
    I have committed all of the patches in my backlog (dense math registers, other
    -mcpu=future instructions, random bug fixes, support for _Float16 and
    __bfloat16, and optimizations for vector logical operations on power10/power11)
    into the IBM vendor branch:
    
            vendors/ibm/gcc-17-future
    
    2026-07-24  Michael Meissner  <[email protected]>
    
    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 fece52794011..45c61dca9890 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 [(BF   "xvcvbf16spn")
@@ -569,3 +573,83 @@
 }
   [(set_attr "length" "12")
    (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 "vsx_register_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 "vsx_register_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;
+})
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.