diff --git a/gcc/testsuite/gcc.target/riscv/bf16-mulbc3-divbc3.c b/gcc/testsuite/gcc.target/riscv/bf16-mulbc3-divbc3.c
new file mode 100644
index 00000000000..5b30de15ccf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/bf16-mulbc3-divbc3.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+#include <complex.h>
+
+typedef _Complex float __cbf16 __attribute__((__mode__(__BC__)));
+
+__cbf16
+divbc3 (__cbf16 rs1, __cbf16 rs2)
+{
+  return rs1 / rs2;
+}
+
+__cbf16
+mulbc3 (__cbf16 rs1, __cbf16 rs2)
+{
+  return rs1 * rs2;
+}
+
+int main()
+{
+  __cbf16 rs1 = 2.0 + 4.0 * I;
+  __cbf16 rs2 = 1.0 + 2.0 * I;
+  __cbf16 mul = -6.0 + 8.0 * I;
+  __cbf16 div = 2.0 + 0.0 * I;
+  if (mulbc3 (rs1, rs2) != mul)
+    __builtin_abort();
+  if (divbc3 (rs1, rs2) != div)
+    __builtin_abort();
+  return 0;
+}
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 0e46e9ef768..b71fd5e2250 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -450,9 +450,9 @@ lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2	   \
 	    _negvsi2 _negvdi2 _ctors _ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2  \
 	    _ctzsi2 _ctzdi2 _popcount_tab _popcountsi2 _popcountdi2	   \
 	    _paritysi2 _paritydi2 _powisf2 _powidf2 _powixf2 _powitf2	   \
-	    _mulhc3 _mulsc3 _muldc3 _mulxc3 _multc3 _divhc3 _divsc3	   \
-	    _divdc3 _divxc3 _divtc3 _bswapsi2 _bswapdi2 _clrsbsi2	   \
-	    _clrsbdi2 _mulbitint3
+	    _mulhc3 _mulbc3 _mulsc3 _muldc3 _mulxc3 _multc3 _divhc3	   \
+	    _divbc3 _divsc3 _divdc3 _divxc3 _divtc3 _bswapsi2 _bswapdi2	   \
+	    _clrsbsi2 _clrsbdi2 _mulbitint3
 
 # The floating-point conversion routines that involve a single-word integer.
 # XX stands for the integer mode.
diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c
index 3fcb85c5b92..1d2aafcfd63 100644
--- a/libgcc/libgcc2.c
+++ b/libgcc/libgcc2.c
@@ -2591,6 +2591,7 @@ NAME (TYPE x, int m)
 #endif
 
 #if((defined(L_mulhc3) || defined(L_divhc3)) && LIBGCC2_HAS_HF_MODE) \
+    || ((defined(L_mulbc3) || defined(L_divbc3)) && LIBGCC2_HAS_BF_MODE) \
     || ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \
     || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \
     || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \
@@ -2607,6 +2608,13 @@ NAME (TYPE x, int m)
 # define MODE	hc
 # define CEXT	__LIBGCC_HF_FUNC_EXT__
 # define NOTRUNC (!__LIBGCC_HF_EXCESS_PRECISION__)
+#elif defined(L_mulbc3) || defined(L_divbc3)
+# define MTYPE  BFtype
+# define CTYPE  BCtype
+# define AMTYPE SFtype
+# define MODE   bc
+# define CEXT   __LIBGCC_BF_FUNC_EXT__
+# define NOTRUNC (!__LIBGCC_BF_EXCESS_PRECISION__)
 #elif defined(L_mulsc3) || defined(L_divsc3)
 # define MTYPE	SFtype
 # define CTYPE	SCtype
@@ -2690,8 +2698,8 @@ extern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1];
 # define TRUNC(x)	__asm__ ("" : "=m"(x) : "m"(x))
 #endif
 
-#if defined(L_mulhc3) || defined(L_mulsc3) || defined(L_muldc3) \
-    || defined(L_mulxc3) || defined(L_multc3)
+#if defined(L_mulhc3) || defined(L_mulbc3) || defined(L_mulsc3)  \
+    || defined(L_muldc3) || defined(L_mulxc3) || defined(L_multc3)
 
 CTYPE
 CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
@@ -2760,16 +2768,16 @@ CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
 }
 #endif /* complex multiply */
 
-#if defined(L_divhc3) || defined(L_divsc3) || defined(L_divdc3) \
-    || defined(L_divxc3) || defined(L_divtc3)
+#if defined(L_divhc3) || defined(L_divbc3) || defined(L_divsc3) \
+    || defined(L_divdc3) || defined(L_divxc3) || defined(L_divtc3)
 
 CTYPE
 CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
 {
-#if defined(L_divhc3)						\
+#if (defined(L_divhc3) || defined(L_divbc3) )			\
   || (defined(L_divsc3) && defined(__LIBGCC_HAVE_HWDBL__) )
 
-  /* Half precision is handled with float precision.
+  /* _Float16 and __bf16 are handled with float precision.
      float is handled with double precision when double precision
      hardware is available.
      Due to the additional precision, the simple complex divide
diff --git a/libgcc/libgcc2.h b/libgcc/libgcc2.h
index b358b3a2b50..ee99badde86 100644
--- a/libgcc/libgcc2.h
+++ b/libgcc/libgcc2.h
@@ -43,6 +43,12 @@ extern void __eprintf (const char *, const char *, unsigned int, const char *)
 #define LIBGCC2_HAS_HF_MODE 0
 #endif
 
+#ifdef __LIBGCC_HAS_BF_MODE__
+#define LIBGCC2_HAS_BF_MODE 1
+#else
+#define LIBGCC2_HAS_BF_MODE 0
+#endif
+
 #ifdef __LIBGCC_HAS_SF_MODE__
 #define LIBGCC2_HAS_SF_MODE 1
 #else
@@ -146,6 +152,10 @@ typedef unsigned int UTItype	__attribute__ ((mode (TI)));
 typedef		float HFtype	__attribute__ ((mode (HF)));
 typedef _Complex float HCtype	__attribute__ ((mode (HC)));
 #endif
+#if LIBGCC2_HAS_BF_MODE
+typedef		float BFtype	__attribute__ ((mode (BF)));
+typedef _Complex float BCtype	__attribute__ ((mode (BC)));
+#endif
 #if LIBGCC2_HAS_SF_MODE
 typedef 	float SFtype	__attribute__ ((mode (SF)));
 typedef _Complex float SCtype	__attribute__ ((mode (SC)));
@@ -465,6 +475,10 @@ extern SItype __negvsi2 (SItype);
 extern HCtype __divhc3 (HFtype, HFtype, HFtype, HFtype);
 extern HCtype __mulhc3 (HFtype, HFtype, HFtype, HFtype);
 #endif
+#if LIBGCC2_HAS_BF_MODE
+extern BCtype __divbc3 (BFtype, BFtype, BFtype, BFtype);
+extern BCtype __mulbc3 (BFtype, BFtype, BFtype, BFtype);
+#endif
 #if LIBGCC2_HAS_SF_MODE
 extern DWtype __fixsfdi (SFtype);
 extern SFtype __floatdisf (DWtype);
