This patch adds convertions between _Float16/__bfloat16 and the other floating point and integer scalar types. It does this by doing the conversion to double as an intermediate type.
All 11 patches have been tested on little endian and big endian PowerPC servers with no regressions. Can I check in these patches? 2025-11-14 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. --- 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 e27428d9486..6805cd99439 100644 --- a/gcc/config/rs6000/float16.md +++ b/gcc/config/rs6000/float16.md @@ -34,6 +34,10 @@ (define_mode_iterator FP16_HW [(BF "TARGET_BFLOAT16_HW") (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 @@ (define_insn "xvcvspbf16_bf" "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; +}) -- 2.51.1 -- Michael Meissner, IBM PO Box 98, Ayer, Massachusetts, USA, 01432 email: [email protected]
