@@ -87,13 +87,13 @@
(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")])
;; 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.
@@ -194,6 +194,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. */
@@ -237,6 +238,21 @@ riscv_init_builtin_types (void)
if (!maybe_get_identifier ("_Float16"))
lang_hooks.types.register_builtin_type (riscv_float16_type_node,
"_Float16");
+
+ /* 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");
}
/* Implement TARGET_INIT_BUILTINS. */
@@ -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. */
@@ -7155,8 +7155,14 @@ static const char *
riscv_mangle_type (const_tree type)
{
/* Half-precision float, _Float16 is "DF16_". */
- if (SCALAR_FLOAT_TYPE_P (type) && TYPE_PRECISION (type) == 16)
+ /* Bfloat, __bf16 is "DF16b" */
+ if (TREE_CODE (type) == REAL_TYPE && TYPE_PRECISION (type) == 16)
+ {
+ if (TYPE_MODE (type) == BFmode)
+ return "DF16b";
+ else
return "DF16_";
+ }
/* Mangle all vector type for vector extension. */
/* The mangle name follows the rule of RVV LLVM
@@ -7177,7 +7183,7 @@ 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);
@@ -7189,7 +7195,7 @@ riscv_scalar_mode_supported_p (scalar_mode mode)
static bool
riscv_libgcc_floating_mode_supported_p (scalar_float_mode mode)
{
- if (mode == HFmode)
+ if (mode == HFmode || BFmode)
return true;
else
return default_libgcc_floating_mode_supported_p (mode);
@@ -169,7 +169,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,VNx128BI,
VNx1QI,VNx2QI,VNx4QI,VNx8QI,VNx16QI,VNx32QI,VNx64QI,VNx128QI,
VNx1HI,VNx2HI,VNx4HI,VNx8HI,VNx16HI,VNx32HI,VNx64HI,
@@ -1744,6 +1744,25 @@
[(set_attr "move_type" "fmove,move,load,store,mtc,mfc")
(set_attr "mode" "HF")])
+;; 16-bit bfloating point moves
+(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_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"))]
+ "(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")])
+
;;
;; ....................
;;
new file mode 100644
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64if -mabi=lp64f -O" } */
+
+__bf16 test_soft_add (__bf16 a, __bf16 b)
+{
+ /* Make sure fadd.s invoked here. */
+ /* { dg-final { scan-assembler-times "call\t__extendbfsf2" 2 } } */
+ return a + b;
+ /* { dg-final { scan-assembler-times "fadd.s" 1 } } */
+ /* { dg-final { scan-assembler-times "call\t__truncsfbf2" 1 } } */
+}
+
@@ -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
@@ -42,7 +42,8 @@ softfp_extras := divsf3 divdf3 divtf3
endif
-softfp_extensions += hfsf hfdf hftf
-softfp_truncations += tfhf dfhf sfhf
+softfp_extensions += hfsf hfdf hftf bfsf
+softfp_truncations += tfhf dfhf sfhf hfbf sfbf dfbf tfbf
softfp_extras += fixhfsi fixhfdi fixunshfsi fixunshfdi \
- floatsihf floatdihf floatunsihf floatundihf
+ floatsihf floatdihf floatunsihf floatundihf \
+ floatdibf floatundibf
@@ -1,4 +1,4 @@
include $(srcdir)/config/riscv/t-softfp32
softfp_int_modes += ti
-softfp_extras += fixhfti fixunshfti floattihf floatuntihf
+softfp_extras += fixhfti fixunshfti floattihf floatuntihf floattibf floatuntibf