From c53c88928f122c0b81d91aa670d818415fee0f4e Mon Sep 17 00:00:00 2001
From: Kuan-Lin Chen <rufus@andestech.com>
Date: Mon, 5 May 2025 14:32:03 +0800
Subject: [PATCH 3/7] RISC-V: Add support for the XAndesbfhcvt ISA extension.

This extension defines instructions to perform scalar floating-point
conversion between the BFLOAT16 floating-point data and the IEEE-754
32-bit single-precision floating-point (SP) data in a scalar
floating point register.

gcc/ChangeLog:

	* config/riscv/andes.def: Add nds_fcvt_s_bf16 and nds_fcvt_bf16_s.
	* config/riscv/andes.md (riscv_nds_fcvt_bf16_s): New pattern.
	(riscv_nds_fcvt_s_bf16): New pattern.
	* config/riscv/riscv-builtins.cc: New AVAIL andesbfhcvt.
	Add new define RISCV_ATYPE_BF and RISCV_ATYPE_SF.
	* config/riscv/riscv-ftypes.def: New DEF_RISCV_FTYPE.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/xandesbfhcvt-1.c: New test.
	* gcc.target/riscv/xandesbfhcvt-2.c: New test.
---
 gcc/config/riscv/andes.def                    |  4 +++
 gcc/config/riscv/andes.md                     | 26 +++++++++++++++++++
 gcc/config/riscv/riscv-builtins.cc            |  3 +++
 gcc/config/riscv/riscv-ftypes.def             |  2 ++
 .../gcc.target/riscv/xandesbfhcvt-1.c         | 11 ++++++++
 .../gcc.target/riscv/xandesbfhcvt-2.c         | 11 ++++++++
 6 files changed, 57 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xandesbfhcvt-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xandesbfhcvt-2.c

diff --git a/gcc/config/riscv/andes.def b/gcc/config/riscv/andes.def
index b864ae712c1d..5b5fb76bfe0e 100644
--- a/gcc/config/riscv/andes.def
+++ b/gcc/config/riscv/andes.def
@@ -8,3 +8,7 @@ RISCV_BUILTIN (nds_ffmismsi, "nds_ffmism", RISCV_BUILTIN_DIRECT, RISCV_LONG_FTYP
 RISCV_BUILTIN (nds_ffmismdi, "nds_ffmism", RISCV_BUILTIN_DIRECT, RISCV_LONG_FTYPE_ULONG_ULONG, andesperf64),
 RISCV_BUILTIN (nds_flmismsi, "nds_flmism", RISCV_BUILTIN_DIRECT, RISCV_LONG_FTYPE_ULONG_ULONG, andesperf32),
 RISCV_BUILTIN (nds_flmismdi, "nds_flmism", RISCV_BUILTIN_DIRECT, RISCV_LONG_FTYPE_ULONG_ULONG, andesperf64),
+
+/* Andes Scalar BFLOAT16 Conversion Extension */
+RISCV_BUILTIN (nds_fcvt_s_bf16, "nds_fcvt_s_bf16", RISCV_BUILTIN_DIRECT, RISCV_SF_FTYPE_BF, andesbfhcvt),
+RISCV_BUILTIN (nds_fcvt_bf16_s, "nds_fcvt_bf16_s", RISCV_BUILTIN_DIRECT, RISCV_BF_FTYPE_SF, andesbfhcvt),
diff --git a/gcc/config/riscv/andes.md b/gcc/config/riscv/andes.md
index 51f61e58e244..22aa5e5150d5 100644
--- a/gcc/config/riscv/andes.md
+++ b/gcc/config/riscv/andes.md
@@ -441,3 +441,29 @@
   "nds.flmism\t%0, %z1, %z2"
   [(set_attr "mode" "<MODE>")
    (set_attr "type" "arith")])
+
+;;
+;;  ....................
+;;
+;;    Bfloat16
+;;
+;;  ....................
+;;
+
+(define_insn "riscv_nds_fcvt_bf16_s"
+  [(set (match_operand:BF   0 "register_operand" "=f")
+	(float_truncate:BF
+	  (match_operand:SF 1 "register_operand" " f")))]
+  "TARGET_XANDESBFHCVT"
+  "nds.fcvt.bf16.s\t%0,%1"
+  [(set_attr "type" "fcvt")
+   (set_attr "mode" "BF")])
+
+(define_insn "riscv_nds_fcvt_s_bf16"
+  [(set (match_operand:SF   0 "register_operand" "=f")
+	(float_extend:SF
+	  (match_operand:BF 1 "register_operand" " f")))]
+  "TARGET_XANDESBFHCVT"
+  "nds.fcvt.s.bf16\t%0,%1"
+  [(set_attr "type" "fcvt")
+   (set_attr "mode" "SF")])
diff --git a/gcc/config/riscv/riscv-builtins.cc b/gcc/config/riscv/riscv-builtins.cc
index 8b081e240be4..799c7a4ccd13 100644
--- a/gcc/config/riscv/riscv-builtins.cc
+++ b/gcc/config/riscv/riscv-builtins.cc
@@ -140,6 +140,7 @@ AVAIL (cvsimd, TARGET_XCVSIMD && !TARGET_64BIT)
 /* ANDES AVAIL.  */
 AVAIL (andesperf32, !TARGET_64BIT && TARGET_XANDESPERF)
 AVAIL (andesperf64, TARGET_64BIT && TARGET_XANDESPERF)
+AVAIL (andesbfhcvt, TARGET_XANDESBFHCVT)
 
 /* Construct a riscv_builtin_description from the given arguments.
 
@@ -199,6 +200,8 @@ AVAIL (andesperf64, TARGET_64BIT && TARGET_XANDESPERF)
 #define RISCV_ATYPE_INT_PTR integer_ptr_type_node
 #define RISCV_ATYPE_ULONG long_unsigned_type_node
 #define RISCV_ATYPE_LONG long_integer_type_node
+#define RISCV_ATYPE_BF bfloat16_type_node
+#define RISCV_ATYPE_SF float_type_node
 
 /* RISCV_FTYPE_ATYPESN takes N RISCV_FTYPES-like type codes and lists
    their associated RISCV_ATYPEs.  */
diff --git a/gcc/config/riscv/riscv-ftypes.def b/gcc/config/riscv/riscv-ftypes.def
index fd1314d9d975..f50a37a581a6 100644
--- a/gcc/config/riscv/riscv-ftypes.def
+++ b/gcc/config/riscv/riscv-ftypes.def
@@ -37,6 +37,8 @@ DEF_RISCV_FTYPE (1, (USI, UQI))
 DEF_RISCV_FTYPE (1, (USI, UHI))
 DEF_RISCV_FTYPE (1, (SI, QI))
 DEF_RISCV_FTYPE (1, (SI, HI))
+DEF_RISCV_FTYPE (1, (BF, SF))
+DEF_RISCV_FTYPE (1, (SF, BF))
 DEF_RISCV_FTYPE (2, (USI, UQI, UQI))
 DEF_RISCV_FTYPE (2, (USI, USI, UHI))
 DEF_RISCV_FTYPE (2, (USI, USI, QI))
diff --git a/gcc/testsuite/gcc.target/riscv/xandesbfhcvt-1.c b/gcc/testsuite/gcc.target/riscv/xandesbfhcvt-1.c
new file mode 100644
index 000000000000..b174b6ef5053
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xandesbfhcvt-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xandesbfhcvt" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xandesbfhcvt" { target { rv64 } } } */
+
+float
+nds_fcvt_s_bf16 (__bf16 a)
+{
+  return __builtin_riscv_nds_fcvt_s_bf16 (a);
+}
+
+/* { dg-final { scan-assembler-times {nds\.fcvt\.s\.bf16} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xandesbfhcvt-2.c b/gcc/testsuite/gcc.target/riscv/xandesbfhcvt-2.c
new file mode 100644
index 000000000000..a2b7665c767d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xandesbfhcvt-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xandesbfhcvt" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xandesbfhcvt" { target { rv64 } } } */
+
+__bf16
+nds_fcvt_bf16_s (float a)
+{
+  return __builtin_riscv_nds_fcvt_bf16_s (a);
+}
+
+/* { dg-final { scan-assembler-times {nds\.fcvt\.bf16\.s} 1 } } */
-- 
2.34.1

