> diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc > index ebc1ed7d7e4..2b3ff1f5b8e 100644 > --- a/gcc/common/config/riscv/riscv-common.cc > +++ b/gcc/common/config/riscv/riscv-common.cc > @@ -102,6 +102,8 @@ static const riscv_implied_info_t riscv_implied_info[] = > {"zvl32768b", "zvl16384b"}, > {"zvl65536b", "zvl32768b"}, > > + {"zfbfmin", "zfhmin"}, > + > {"zfh", "zfhmin"}, > {"zfhmin", "f"}, > > @@ -1239,6 +1241,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] = > {"zvl16384b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL16384B}, > {"zvl32768b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL32768B}, > {"zvl65536b", &gcc_options::x_riscv_zvl_flags, MASK_ZVL65536B}, > + > + {"zfbfmin", &gcc_options::x_riscv_zf_subext, MASK_ZFBFMIN}, > > {"zfhmin", &gcc_options::x_riscv_zf_subext, MASK_ZFHMIN}, > {"zfh", &gcc_options::x_riscv_zf_subext, MASK_ZFH}, As kito says, there is no version information for the extension. > diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md > index 5b70ab20758..6349f032bc8 100644 > --- a/gcc/config/riscv/iterators.md > +++ b/gcc/config/riscv/iterators.md > @@ -61,10 +61,15 @@ > ;; Iterator for hardware-supported floating-point modes. > (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT || TARGET_ZFINX") > (DF "TARGET_DOUBLE_FLOAT || TARGET_ZDINX") > - (HF "TARGET_ZFH || TARGET_ZHINX")]) > + (HF "TARGET_ZFH || TARGET_ZHINX") > + (BF "TARGET_ZFBFMIN")]) > + > +;; Iterator for HImode constant generation. > +(define_mode_iterator BFHF [BF HF]) > > ;; Iterator for floating-point modes that can be loaded into X registers. > -(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF "TARGET_ZFHMIN")]) > +(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF "TARGET_ZFHMIN") > + (BF "TARGET_ZFBFMIN")]) > > > ;; ------------------------------------------------------------------- > @@ -76,27 +81,27 @@ > (define_mode_attr size [(QI "b") (HI "h")]) > > ;; Mode attributes for loads. > -(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (HF "flh") (SF "flw") (DF "fld")]) > +(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (BF "flh") (HF "flh") (SF "flw") (DF "fld")]) > > ;; Instruction names for integer loads that aren't explicitly sign or zero > ;; extended. See riscv_output_move and LOAD_EXTEND_OP. > (define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")]) > > ;; Mode attribute for FP loads into integer registers. > -(define_mode_attr softload [(HF "lh") (SF "lw") (DF "ld")]) > +(define_mode_attr softload [(BF "lh") (HF "lh") (SF "lw") (DF "ld")]) > > ;; Instruction names for stores. > -(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (HF "fsh") (SF "fsw") (DF "fsd")]) > +(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (BF "fsh") (HF "fsh") (SF "fsw") (DF "fsd")]) > > ;; Instruction names for FP stores from integer registers. > -(define_mode_attr softstore [(HF "sh") (SF "sw") (DF "sd")]) > +(define_mode_attr softstore [(BF "sh") (HF "sh") (SF "sw") (DF "sd")]) > > ;; This attribute gives the best constraint to use for registers of > ;; a given mode. > (define_mode_attr reg [(SI "d") (DI "d") (CC "d")]) > > ;; This attribute gives the format suffix for floating-point operations. > -(define_mode_attr fmt [(HF "h") (SF "s") (DF "d")]) > +(define_mode_attr fmt [(BF "h") (HF "h") (SF "s") (DF "d")]) > > ;; This attribute gives the integer suffix for floating-point conversions. > (define_mode_attr ifmt [(SI "w") (DI "l")]) > @@ -106,7 +111,7 @@ > > ;; This attribute gives the upper-case mode name for one unit of a > ;; floating-point mode. > -(define_mode_attr UNITMODE [(HF "HF") (SF "SF") (DF "DF")]) > +(define_mode_attr UNITMODE [(BF "BF") (HF "HF") (SF "SF") (DF "DF")]) > > ;; This attribute gives the integer mode that has half the size of > ;; the controlling mode. > diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc > index 25ca407f9a9..e0c6f6834a5 100644 > --- a/gcc/config/riscv/riscv-builtins.cc > +++ b/gcc/config/riscv/riscv-builtins.cc > @@ -163,6 +163,7 @@ static GTY(()) int riscv_builtin_decl_index[NUM_INSN_CODES]; > riscv_builtin_decls[riscv_builtin_decl_index[(CODE)]] > > tree riscv_float16_type_node = NULL_TREE; > +tree riscv_bfloat16_type_node = NULL_TREE; > > /* Return the function type associated with function prototype TYPE. */ > > @@ -190,7 +191,7 @@ riscv_build_function_type (enum riscv_function_type type) > } > > static void > -riscv_init_builtin_types (void) > +riscv_fp16_builtin_type (void) > { > /* Provide the _Float16 type and float16_type_node if needed. */ > if (!float16_type_node) > @@ -208,6 +209,32 @@ riscv_init_builtin_types (void) > "_Float16"); > } > > +static void > +riscv_bf16_builtin_type (void) > +{ > + /* Provide the _bf16 type and bfloat16_type_node if needed. */ > + if (!bfloat16_type_node) > + { > + riscv_bfloat16_type_node = make_node (REAL_TYPE); > + TYPE_PRECISION (riscv_bfloat16_type_node) = 16; > + SET_TYPE_MODE (riscv_bfloat16_type_node, BFmode); > + layout_type (riscv_bfloat16_type_node); > + } > + else > + riscv_bfloat16_type_node = bfloat16_type_node; > + > + if (!maybe_get_identifier ("__bf16")) > + lang_hooks.types.register_builtin_type (riscv_bfloat16_type_node, > + "__bf16"); > +} > + > +static void > +riscv_init_builtin_types (void) > +{ > + riscv_fp16_builtin_type (); > + riscv_bf16_builtin_type (); > +} > + > /* Implement TARGET_INIT_BUILTINS. */ > > void > diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def > index d5305efa8a6..93c22b09ed7 100644 > --- a/gcc/config/riscv/riscv-modes.def > +++ b/gcc/config/riscv/riscv-modes.def > @@ -21,6 +21,8 @@ along with GCC; see the file COPYING3. If not see > > FLOAT_MODE (HF, 2, ieee_half_format); > FLOAT_MODE (TF, 16, ieee_quad_format); > +FLOAT_MODE (BF, 2, 0); > +ADJUST_FLOAT_FORMAT (BF, &arm_bfloat_half_format); > > /* Vector modes. */ > > diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h > index ff398c0a2ae..e5791019912 100644 > --- a/gcc/config/riscv/riscv-opts.h > +++ b/gcc/config/riscv/riscv-opts.h > @@ -168,9 +168,11 @@ enum stack_protector_guard { > > #define MASK_ZFHMIN (1 << 0) > #define MASK_ZFH (1 << 1) > +#define MASK_ZFBFMIN (1 << 2) > > #define TARGET_ZFHMIN ((riscv_zf_subext & MASK_ZFHMIN) != 0) > #define TARGET_ZFH ((riscv_zf_subext & MASK_ZFH) != 0) > +#define TARGET_ZFBFMIN ((riscv_zf_subext & MASK_ZFBFMIN) != 0) > > #define MASK_ZMMUL (1 << 0) > #define TARGET_ZMMUL ((riscv_zm_subext & MASK_ZMMUL) != 0) > diff --git a/gcc/config/riscv/riscv-vector-switch.def b/gcc/config/riscv/riscv-vector-switch.def > index 8e4aed40338..8808d0f9b44 100644 > --- a/gcc/config/riscv/riscv-vector-switch.def > +++ b/gcc/config/riscv/riscv-vector-switch.def > @@ -75,7 +75,7 @@ n = SEW/LMUL > |Types|n=1 |n=2 |n=4 |n=8 |n=16 |n=32 |n=64| > |bool |VNx32BI|VNx16BI|VNx8BI|VNx4BI|VNx2BI|VNx1BI|N/A | > > -TODO: FP16 vector needs support of 'zvfh', we don't support it yet. */ > +TODO: FP16 vector needs support of 'zvfh' and 'zvfbfmin', we don't support it yet. */ > > /* Return 'REQUIREMENT' for machine_mode 'MODE'. > For example: 'MODE' = VNx64BImode needs TARGET_MIN_VLEN > 32. */ > @@ -120,7 +120,7 @@ ENTRY (VNx4HI, true, LMUL_2, 8, LMUL_1, 16) > ENTRY (VNx2HI, true, LMUL_1, 16, LMUL_F2, 32) > ENTRY (VNx1HI, true, LMUL_F2, 32, LMUL_F4, 64) > > -/* TODO:Disable all FP16 vector, enable them when 'zvfh' is supported. */ > +/* TODO:Disable all FP16 vector, enable them when 'zvfh' and 'zvfbfmin' is supported. */ > ENTRY (VNx32HF, false, LMUL_RESERVED, 0, LMUL_8, 2) > ENTRY (VNx16HF, false, LMUL_8, 2, LMUL_4, 4) > ENTRY (VNx8HF, false, LMUL_4, 4, LMUL_2, 8) > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index f11b7949a49..2ddbdfa424a 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -3192,7 +3192,11 @@ riscv_emit_float_compare (enum rtx_code *code, rtx *op0, rtx *op1) > else if (GET_MODE (cmp_op0) == HFmode && TARGET_64BIT) \ > emit_insn (gen_f##CMP##_quiethfdi4 (*op0, cmp_op0, cmp_op1)); \ > else if (GET_MODE (cmp_op0) == HFmode) \ > - emit_insn (gen_f##CMP##_quiethfsi4 (*op0, cmp_op0, cmp_op1)); \ > + emit_insn (gen_f##CMP##_quietbfsi4 (*op0, cmp_op0, cmp_op1)); \ > + else if (GET_MODE (cmp_op0) == BFmode && TARGET_64BIT) \ > + emit_insn (gen_f##CMP##_quietbfdi4 (*op0, cmp_op0, cmp_op1)); \ > + else if (GET_MODE (cmp_op0) == BFmode) \ > + emit_insn (gen_f##CMP##_quietbfsi4 (*op0, cmp_op0, cmp_op1)); \ > else \ > gcc_unreachable (); \ > *op1 = const0_rtx; \ > @@ -6699,7 +6703,13 @@ riscv_mangle_type (const_tree type) > { > /* Half-precision float, _Float16 is "DF16_". */ > if (TREE_CODE (type) == REAL_TYPE && TYPE_PRECISION (type) == 16) > - return "DF16_"; > + { > + if (TYPE_MAIN_VARIANT (type) == float16_type_node) > + return "DF16_"; The conditions here are very likely to be false, even if "TYPE_MODE (type) == HFmode", there may be a risk of ICE, I'm not sure. > + > + if (TYPE_MODE (type) == BFmode) > + return "DF16b"; > + } > > /* Mangle all vector type for vector extension. */ > /* The mangle name follows the rule of RVV LLVM > @@ -6720,19 +6730,19 @@ riscv_mangle_type (const_tree type) > static bool > riscv_scalar_mode_supported_p (scalar_mode mode) > { > - if (mode == HFmode) > + if (mode == HFmode || mode == BFmode) > return true; > else > return default_scalar_mode_supported_p (mode); > } > > /* Implement TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P - return TRUE > - if MODE is HFmode, and punt to the generic implementation otherwise. */ > + if MODE is HFmode or BFmode, and punt to the generic implementation otherwise. */ > > static bool > riscv_libgcc_floating_mode_supported_p (scalar_float_mode mode) > { > - if (mode == HFmode) > + if (mode == HFmode || mode == BFmode) > return true; > else > return default_libgcc_floating_mode_supported_p (mode); > @@ -6804,6 +6814,23 @@ riscv_init_libfuncs (void) > set_optab_libfunc (ge_optab, HFmode, NULL); > set_optab_libfunc (gt_optab, HFmode, NULL); > set_optab_libfunc (unord_optab, HFmode, NULL); > + > + /* Bfloat16*/ > + /* Arithmetic. */ > + set_optab_libfunc (add_optab, BFmode, NULL); > + set_optab_libfunc (sdiv_optab, BFmode, NULL); > + set_optab_libfunc (smul_optab, BFmode, NULL); > + set_optab_libfunc (neg_optab, BFmode, NULL); > + set_optab_libfunc (sub_optab, BFmode, NULL); > + > + /* Comparisons. */ > + set_optab_libfunc (eq_optab, BFmode, NULL); > + set_optab_libfunc (ne_optab, BFmode, NULL); > + set_optab_libfunc (lt_optab, BFmode, NULL); > + set_optab_libfunc (le_optab, BFmode, NULL); > + set_optab_libfunc (ge_optab, BFmode, NULL); > + set_optab_libfunc (gt_optab, BFmode, NULL); > + set_optab_libfunc (unord_optab, BFmode, NULL); > } > > #if CHECKING_P > diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md > index 05924e9bbf1..89b10bada5e 100644 > --- a/gcc/config/riscv/riscv.md > +++ b/gcc/config/riscv/riscv.md > @@ -158,7 +158,7 @@ > (const_string "unknown")) > > ;; Main data type used by the insn > -(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,HF,SF,DF,TF, > +(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,BF,HF,SF,DF,TF, > VNx1BI,VNx2BI,VNx4BI,VNx8BI,VNx16BI,VNx32BI,VNx64BI, > VNx1QI,VNx2QI,VNx4QI,VNx8QI,VNx16QI,VNx32QI,VNx64QI, > VNx1HI,VNx2HI,VNx4HI,VNx8HI,VNx16HI,VNx32HI, > @@ -1330,15 +1330,25 @@ > [(set_attr "type" "fcvt") > (set_attr "mode" "HF")]) > > -(define_insn "truncdfhf2" > - [(set (match_operand:HF 0 "register_operand" "=f") > - (float_truncate:HF > +(define_insn "truncsfbf2" > + [(set (match_operand:BF 0 "register_operand" "=f") > + (float_truncate:BF > + (match_operand:SF 1 "register_operand" " f")))] > + "TARGET_ZFBFMIN" > + "fcvt.bf16.s\t%0,%1" > + [(set_attr "type" "fcvt") > + (set_attr "mode" "BF")]) > + > +(define_insn "truncdf2" > + [(set (match_operand:BFHF 0 "register_operand" "=f") > + (float_truncate:BFHF > (match_operand:DF 1 "register_operand" " f")))] > "(TARGET_ZFHMIN && TARGET_DOUBLE_FLOAT) || > - (TARGET_ZHINXMIN && TARGET_ZDINX)" > + (TARGET_ZHINXMIN && TARGET_ZDINX) || > + (TARGET_ZFBFMIN && TARGET_DOUBLE_FLOAT)" > "fcvt.h.d\t%0,%1" > [(set_attr "type" "fcvt") > - (set_attr "mode" "HF")]) > + (set_attr "mode" "")]) > This may not be correct, because when double is converted to__bf16, it should be converted to float first and then to__bf16. Right? > ;; > ;; .................... > @@ -1466,6 +1476,15 @@ > [(set_attr "type" "fcvt") > (set_attr "mode" "SF")]) > > +(define_insn "extendbfsf2" > + [(set (match_operand:SF 0 "register_operand" "=f") > + (float_extend:SF > + (match_operand:BF 1 "register_operand" " f")))] > + "TARGET_ZFBFMIN" > + "fcvt.s.bf16\t%0,%1" > + [(set_attr "type" "fcvt") > + (set_attr "mode" "SF")]) > + > (define_insn "extendsfdf2" > [(set (match_operand:DF 0 "register_operand" "=f") > (float_extend:DF > @@ -1475,15 +1494,16 @@ > [(set_attr "type" "fcvt") > (set_attr "mode" "DF")]) > > -(define_insn "extendhfdf2" > +(define_insn "extenddf2" > [(set (match_operand:DF 0 "register_operand" "=f") > (float_extend:DF > - (match_operand:HF 1 "register_operand" " f")))] > + (match_operand:BFHF 1 "register_operand" " f")))] > "(TARGET_ZFHMIN && TARGET_DOUBLE_FLOAT) || > - (TARGET_ZHINXMIN && TARGET_ZDINX)" > + (TARGET_ZHINXMIN && TARGET_ZDINX) || > + (TARGET_ZFBFMIN && TARGET_DOUBLE_FLOAT)" > "fcvt.d.h\t%0,%1" > [(set_attr "type" "fcvt") > - (set_attr "mode" "DF")]) > + (set_attr "mode" "")]) > Same problem with truncdfbf2. > ;; 16-bit floating point moves > (define_expand "movhf" > @@ -1515,6 +1535,35 @@ > [(set_attr "move_type" "fmove,move,load,store,mtc,mfc") > (set_attr "mode" "HF")]) > > +(define_expand "movbf" > + [(set (match_operand:BF 0 "") > + (match_operand:BF 1 ""))] > + "" > +{ > + if (riscv_legitimize_move (BFmode, operands[0], operands[1])) > + DONE; > +}) > + > +(define_insn "*movbf_hardfloat" > + [(set (match_operand:BF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*r, *r,*r,*m") > + (match_operand:BF 1 "move_operand" " f,G,m,f,G,*r,*f,*G*r,*m,*r"))] > + "TARGET_ZFBFMIN > + && (register_operand (operands[0], BFmode) > + || reg_or_0_operand (operands[1], BFmode))" > + { return riscv_output_move (operands[0], operands[1]); } > + [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") > + (set_attr "mode" "BF")]) > + > +(define_insn "*movbf_softfloat" > + [(set (match_operand:BF 0 "nonimmediate_operand" "=f, r,r,m,*f,*r") > + (match_operand:BF 1 "move_operand" " f,Gr,m,r,*r,*f"))] > + "!TARGET_ZFHMIN > + && (register_operand (operands[0], BFmode) > + || reg_or_0_operand (operands[1], BFmode))" > + { return riscv_output_move (operands[0], operands[1]); } > + [(set_attr "move_type" "fmove,move,load,store,mtc,mfc") > + (set_attr "mode" "BF")]) > + Maybe merge with movhf, movhf_hardfloat and *movhf_softfloat? > ;; > ;; .................... > ;; > diff --git a/libgcc/config/riscv/sfp-machine.h b/libgcc/config/riscv/sfp-machine.h > index ded594d75d8..2ed7cbf3a30 100644 > --- a/libgcc/config/riscv/sfp-machine.h > +++ b/libgcc/config/riscv/sfp-machine.h > @@ -41,6 +41,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) > #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) > > +#define _FP_NANFRAC_B _FP_QNANBIT_B > #define _FP_NANFRAC_H _FP_QNANBIT_H > #define _FP_NANFRAC_S _FP_QNANBIT_S > #define _FP_NANFRAC_D _FP_QNANBIT_D, 0 > @@ -64,6 +65,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y) > #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y) > > +#define _FP_NANFRAC_B _FP_QNANBIT_B > #define _FP_NANFRAC_H _FP_QNANBIT_H > #define _FP_NANFRAC_S _FP_QNANBIT_S > #define _FP_NANFRAC_D _FP_QNANBIT_D > @@ -82,6 +84,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); > typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); > #define CMPtype __gcc_CMPtype > > +#define _FP_NANSIGN_B 0 > #define _FP_NANSIGN_H 0 > #define _FP_NANSIGN_S 0 > #define _FP_NANSIGN_D 0 > diff --git a/libgcc/config/riscv/t-softfp32 b/libgcc/config/riscv/t-softfp32 > index 55261f98383..dc85ff79c1c 100644 > --- a/libgcc/config/riscv/t-softfp32 > +++ b/libgcc/config/riscv/t-softfp32 > @@ -42,7 +42,9 @@ softfp_extras := divsf3 divdf3 divtf3 > > endif > > -softfp_extensions += hfsf hfdf hftf > -softfp_truncations += tfhf dfhf sfhf > +softfp_extensions += hfsf hfdf hftf bfsf bfdf bftf bfdf and bftf do not seem to be implemented > +softfp_truncations += tfhf dfhf sfhf tfbf dfbf sfhf sfhf repeat, the last one should be sfbf hfbf may also be required? > softfp_extras += fixhfsi fixhfdi fixunshfsi fixunshfdi \ > - floatsihf floatdihf floatunsihf floatundihf > + floatsihf floatdihf floatunsihf floatundihf \ > + fixbfsi fixbfdi fixunsbfsi fixunsbfdi \ > + floatsibf floatdibf floatunsibf floatundibf fixbfsi, fixbfdi, fixunsbfsi, fixunsbfdi, floatsibf and floatunsibf do not seem to be implemented.