public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Add bfloat16_t support for riscv
@ 2023-06-16  4:31 Liao Shihua
  0 siblings, 0 replies; only message in thread
From: Liao Shihua @ 2023-06-16  4:31 UTC (permalink / raw)
  To: gcc-patches
  Cc: kito.cheng, palmer, lazyparser, jiawei, jinma, juzhe.zhong,
	shiyulong, chenyixuan, Liao Shihua

    x86_64/i686/AArch64 has for a few months working std::bfloat16_t
    support, __bf16 there is no longer a storage only type, but can 
    be used for arithmetics and is supported in libgcc and libstdc++. 
    The patch adds similar support for RISC-V. __bf16 has been merged 
    in psABI. The compiler handles all operations with __bf16 by 
    converting to SFmode.

gcc/ChangeLog:

        * config/riscv/iterators.md (ld):Add BFmode in iterators.
        (sd):Ditto.
        * config/riscv/riscv-builtins.cc (riscv_init_builtin_types):Add bfloat16_type_node in riscv.
        * config/riscv/riscv-modes.def (FLOAT_MODE):Add BFmode in FLOAT_MODE.
        (ADJUST_FLOAT_FORMAT):Ditto.
        * config/riscv/riscv.cc (riscv_mangle_type):Add DF16b in mangle.
        (riscv_scalar_mode_supported_p):Add BFmode in scalar_float_mode.
        (riscv_libgcc_floating_mode_supported_p):Support BFmode in libgcc.
        * config/riscv/riscv.md (mode" ):Support BFmode in machine description.
        (movbf): Support BFmode in softfloat.
        (*movbf_softfloat):Ditto.

libgcc/ChangeLog:

        * config/riscv/sfp-machine.h (_FP_NANFRAC_B):Define.
        (_FP_NANSIGN_B):
        * config/riscv/t-softfp32:Add trunc{tfbf dfbf sfbf hfbf}, extendbfsf, floatdibf, floatundibf.
        * config/riscv/t-softfp64:Add floattibf, floatuntibf.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/__bf16-soft.c: New test.

---
 gcc/config/riscv/iterators.md                |  4 ++--
 gcc/config/riscv/riscv-builtins.cc           | 16 +++++++++++++++
 gcc/config/riscv/riscv-modes.def             |  2 ++
 gcc/config/riscv/riscv.cc                    | 12 ++++++++---
 gcc/config/riscv/riscv.md                    | 21 +++++++++++++++++++-
 gcc/testsuite/gcc.target/riscv/__bf16-soft.c | 12 +++++++++++
 libgcc/config/riscv/sfp-machine.h            |  3 +++
 libgcc/config/riscv/t-softfp32               |  7 ++++---
 libgcc/config/riscv/t-softfp64               |  2 +-
 9 files changed, 69 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/__bf16-soft.c

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index d374a10810c..c9148028ea3 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -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.
diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc
index 79681d75962..398247a0ccb 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -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.  */
diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
index 19a4f9fb3db..4bb03307840 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.cc b/gcc/config/riscv/riscv.cc
index e5ae4e81b7a..d5b1350d4bf 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -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);
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index d8e935cb934..77b52862bbd 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -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")])
+
 ;;
 ;;  ....................
 ;;
diff --git a/gcc/testsuite/gcc.target/riscv/__bf16-soft.c b/gcc/testsuite/gcc.target/riscv/__bf16-soft.c
new file mode 100644
index 00000000000..eca98a799d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/__bf16-soft.c
@@ -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 } } */
+}
+
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..25ac9f07541 100644
--- a/libgcc/config/riscv/t-softfp32
+++ b/libgcc/config/riscv/t-softfp32
@@ -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
diff --git a/libgcc/config/riscv/t-softfp64 b/libgcc/config/riscv/t-softfp64
index c87d242d5c3..6f8c21352b6 100644
--- a/libgcc/config/riscv/t-softfp64
+++ b/libgcc/config/riscv/t-softfp64
@@ -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
-- 
2.34.1



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-16  4:32 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-16  4:31 [PATCH] Add bfloat16_t support for riscv Liao Shihua

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).