public inbox for qemu-devel@nongnu.org
 help / color / mirror / Atom feed
* [PATCH v5 0/9] Add Zvfbfa extension support
@ 2026-03-06  7:10 Max Chou
  2026-03-06  7:10 ` [PATCH v5 1/9] target/riscv: Add cfg properties for Zvfbfa extensions Max Chou
                   ` (9 more replies)
  0 siblings, 10 replies; 28+ messages in thread
From: Max Chou @ 2026-03-06  7:10 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Chou

This patch series adds support for the RISC-V Zvfbfa extension, which
provides additional BF16 vector compute support.

The isa spec of Zvfbfa extension is not ratified yet, so this patch
series is based on the latest draft of the spec (v0.1) and make the
Zvfbfa extension as an experimental extension.

The Zvfbfa extension adds a 1-bit field, altfmt, to the vtype CSR in
bit position 8.
The Zvfbfa extension requires the Zve32f and Zfbfmin extensions.

Specification:
https://github.com/aswaterman/riscv-misc/blob/main/isa/zvfbfa.adoc

Changes in v5:
- Fix typo in patch 1/5/8
- Remove unnecessary do_bf16_nanbox

Changes in v4:
- Rebase on riscv-to-apply.next (commit 21101a7)
- Update commit message of patch 2 (target/riscv: Add the Zvfbfa
  extension implied rule)
- Update checking flow of illegal ALTFMT SEW patterns at patch 3
  (target/riscv: rvv: Add new VTYPE CSR field - altfmt)

Changes in v3:
- Rebased on riscv-to-apply.next (commit f66f234)
- Fix typo in v2 patch 5 commit message

Changes from v2:
- Removed RFC designation from the series
- Updated commit message for patch 3 (VTYPE CSR field -
  altfmt) to clearly explain:
  * VEDIV field removal (bits 8-9) since EDIV extension is not
    planned to be part of the base V extension
  * ALTFMT field addition at bit 8
  * RESERVED field change from bit 10 to bit 9
- Added new patch 4: Introduce reset_ill_vtype helper function to
  consolidate illegal vtype CSR reset logic

v4: <20260304132514.2889449-1-max.chou@sifive.com>
v3: <20260127014227.406653-1-max.chou@sifive.com>
v2: <20260108132631.9429-1-max.chou@sifive.com>
v1: <20250915084037.1816893-1-max.chou@sifive.com>

rnax


Max Chou (9):
  target/riscv: Add cfg properties for Zvfbfa extensions
  target/riscv: Add the Zvfbfa extension implied rule
  target/riscv: rvv: Add new VTYPE CSR field - altfmt
  target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype
    CSR
  target/riscv: Use the tb->cs_base as the extend tb flags
  target/riscv: Introduce altfmt into DisasContext
  target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension
  target/riscv: rvv: Support Zvfbfa vector bf16 operations
  target/riscv: Expose Zvfbfa extension as an experimental cpu property

 include/exec/translation-block.h        |   1 +
 target/riscv/cpu.c                      |  15 +-
 target/riscv/cpu.h                      |   7 +-
 target/riscv/cpu_cfg_fields.h.inc       |   1 +
 target/riscv/helper.h                   |  60 ++
 target/riscv/insn_trans/trans_rvv.c.inc | 988 +++++++++++++++---------
 target/riscv/internals.h                |   1 +
 target/riscv/tcg/tcg-cpu.c              |  15 +-
 target/riscv/translate.c                |  11 +
 target/riscv/vector_helper.c            | 389 +++++++++-
 10 files changed, 1088 insertions(+), 400 deletions(-)

-- 
2.52.0



^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH v5 1/9] target/riscv: Add cfg properties for Zvfbfa extensions
  2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
@ 2026-03-06  7:10 ` Max Chou
  2026-03-09  4:44   ` Alistair Francis
  2026-03-06  7:10 ` [PATCH v5 2/9] target/riscv: Add the Zvfbfa extension implied rule Max Chou
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Max Chou @ 2026-03-06  7:10 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Chou,
	Daniel Henrique Barboza, Nutty Liu

The Zvfbfa extension adds more complete BF16 vector compute support
and requires the Zve32f and Zfbfmin extensions.

Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
---
 target/riscv/cpu.c                | 1 +
 target/riscv/cpu_cfg_fields.h.inc | 1 +
 target/riscv/tcg/tcg-cpu.c        | 8 ++++++++
 3 files changed, 10 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9be79622f4..2ddc26c837 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -189,6 +189,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
     ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
     ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
     ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
+    ISA_EXT_DATA_ENTRY(zvfbfa, PRIV_VERSION_1_13_0, ext_zvfbfa),
     ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
     ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
     ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
index 70ec650abf..3696f02ee0 100644
--- a/target/riscv/cpu_cfg_fields.h.inc
+++ b/target/riscv/cpu_cfg_fields.h.inc
@@ -99,6 +99,7 @@ BOOL_FIELD(ext_zvks)
 BOOL_FIELD(ext_zvksc)
 BOOL_FIELD(ext_zvksg)
 BOOL_FIELD(ext_zmmul)
+BOOL_FIELD(ext_zvfbfa)
 BOOL_FIELD(ext_zvfbfmin)
 BOOL_FIELD(ext_zvfbfwma)
 BOOL_FIELD(ext_zvfh)
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 988b2d905f..720ff0c2a3 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -720,6 +720,14 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         return;
     }
 
+    if (cpu->cfg.ext_zvfbfa) {
+        if (!cpu->cfg.ext_zve32f || !cpu->cfg.ext_zfbfmin) {
+            error_setg(errp, "Zvfbfa extension requires Zve32f extension "
+                             "and Zfbfmin extension");
+            return;
+        }
+    }
+
     if ((cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinxmin) && !cpu->cfg.ext_zfinx) {
         error_setg(errp, "Zdinx/Zhinx/Zhinxmin extensions require Zfinx");
         return;
-- 
2.52.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v5 2/9] target/riscv: Add the Zvfbfa extension implied rule
  2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
  2026-03-06  7:10 ` [PATCH v5 1/9] target/riscv: Add cfg properties for Zvfbfa extensions Max Chou
@ 2026-03-06  7:10 ` Max Chou
  2026-03-09  4:45   ` Alistair Francis
  2026-03-06  7:10 ` [PATCH v5 3/9] target/riscv: rvv: Add new VTYPE CSR field - altfmt Max Chou
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Max Chou @ 2026-03-06  7:10 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Chou,
	Daniel Henrique Barboza, Nutty Liu

According to the Zvfbfa isa spec:
The Zvfbfa extension requires the Zve32f and Zfbfmin extensions.

Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
---
 target/riscv/cpu.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 2ddc26c837..376517755e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -2619,6 +2619,15 @@ static RISCVCPUImpliedExtsRule SSCTR_IMPLIED = {
     },
 };
 
+static RISCVCPUImpliedExtsRule ZVFBFA_IMPLIED = {
+    .ext = CPU_CFG_OFFSET(ext_zvfbfa),
+    .implied_multi_exts = {
+        CPU_CFG_OFFSET(ext_zve32f), CPU_CFG_OFFSET(ext_zfbfmin),
+
+        RISCV_IMPLIED_EXTS_RULE_END
+    },
+};
+
 RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[] = {
     &RVA_IMPLIED, &RVD_IMPLIED, &RVF_IMPLIED,
     &RVM_IMPLIED, &RVV_IMPLIED, NULL
@@ -2632,8 +2641,8 @@ RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[] = {
     &ZHINX_IMPLIED, &ZHINXMIN_IMPLIED, &ZICNTR_IMPLIED,
     &ZIHPM_IMPLIED, &ZK_IMPLIED, &ZKN_IMPLIED,
     &ZKS_IMPLIED, &ZVBB_IMPLIED, &ZVE32F_IMPLIED,
-    &ZVE32X_IMPLIED, &ZVE64D_IMPLIED, &ZVE64F_IMPLIED,
-    &ZVE64X_IMPLIED, &ZVFBFMIN_IMPLIED, &ZVFBFWMA_IMPLIED,
+    &ZVE32X_IMPLIED, &ZVE64D_IMPLIED, &ZVE64F_IMPLIED, &ZVE64X_IMPLIED,
+    &ZVFBFA_IMPLIED, &ZVFBFMIN_IMPLIED, &ZVFBFWMA_IMPLIED,
     &ZVFH_IMPLIED, &ZVFHMIN_IMPLIED, &ZVKN_IMPLIED,
     &ZVKNC_IMPLIED, &ZVKNG_IMPLIED, &ZVKNHB_IMPLIED,
     &ZVKS_IMPLIED,  &ZVKSC_IMPLIED, &ZVKSG_IMPLIED, &SSCFG_IMPLIED,
-- 
2.52.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v5 3/9] target/riscv: rvv: Add new VTYPE CSR field - altfmt
  2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
  2026-03-06  7:10 ` [PATCH v5 1/9] target/riscv: Add cfg properties for Zvfbfa extensions Max Chou
  2026-03-06  7:10 ` [PATCH v5 2/9] target/riscv: Add the Zvfbfa extension implied rule Max Chou
@ 2026-03-06  7:10 ` Max Chou
  2026-03-09  4:55   ` Alistair Francis
  2026-03-16  9:20   ` Nutty.Liu
  2026-03-06  7:10 ` [PATCH v5 4/9] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR Max Chou
                   ` (6 subsequent siblings)
  9 siblings, 2 replies; 28+ messages in thread
From: Max Chou @ 2026-03-06  7:10 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Chou,
	Daniel Henrique Barboza

According to the Zvfbfa ISA spec v0.1, the vtype CSR adds a new field:
altfmt for BF16 support.
This update changes the layout of the vtype CSR fields.

- Removed VEDIV field (bits 8-9) since EDIV extension is not planned to
  be part of the base V extension
- Added ALTFMT field at bit 8
- Changed RESERVED field to start from bit 9 instead of bit 10

When Zvfbfa is disabled, bits 8+ are treated as reserved (preserving
existing behavior for altfmt bit). When Zvfbfa is enabled, only bits 9+
are reserved.

Reference:
- https://github.com/riscvarchive/riscv-v-spec/blob/master/ediv.adoc

Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
---
 target/riscv/cpu.h           |  4 ++--
 target/riscv/vector_helper.c | 39 +++++++++++++++++++++++++++++++-----
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 35d1f6362c..962cc45073 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -191,8 +191,8 @@ FIELD(VTYPE, VLMUL, 0, 3)
 FIELD(VTYPE, VSEW, 3, 3)
 FIELD(VTYPE, VTA, 6, 1)
 FIELD(VTYPE, VMA, 7, 1)
-FIELD(VTYPE, VEDIV, 8, 2)
-FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
+FIELD(VTYPE, ALTFMT, 8, 1)
+FIELD(VTYPE, RESERVED, 9, sizeof(target_ulong) * 8 - 10)
 
 typedef struct PMUCTRState {
     /* Current value of a counter */
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index caa8dd9c12..7575e24084 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -33,6 +33,22 @@
 #include "vector_internals.h"
 #include <math.h>
 
+static target_ulong vtype_reserved(CPURISCVState *env, target_ulong vtype)
+{
+    int xlen = riscv_cpu_xlen(env);
+    target_ulong reserved = 0;
+
+    if (riscv_cpu_cfg(env)->ext_zvfbfa) {
+        reserved = vtype & MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
+                                           xlen - 1 - R_VTYPE_RESERVED_SHIFT);
+    } else {
+        reserved = vtype & MAKE_64BIT_MASK(R_VTYPE_ALTFMT_SHIFT,
+                                           xlen - 1 - R_VTYPE_ALTFMT_SHIFT);
+    }
+
+    return reserved;
+}
+
 target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
                             target_ulong s2, target_ulong x0)
 {
@@ -41,12 +57,10 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
     uint64_t vlmul = FIELD_EX64(s2, VTYPE, VLMUL);
     uint8_t vsew = FIELD_EX64(s2, VTYPE, VSEW);
     uint16_t sew = 8 << vsew;
-    uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
+    uint8_t altfmt = FIELD_EX64(s2, VTYPE, ALTFMT);
+    bool ill_altfmt = true;
     int xlen = riscv_cpu_xlen(env);
     bool vill = (s2 >> (xlen - 1)) & 0x1;
-    target_ulong reserved = s2 &
-                            MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
-                                            xlen - 1 - R_VTYPE_RESERVED_SHIFT);
     uint16_t vlen = cpu->cfg.vlenb << 3;
     int8_t lmul;
 
@@ -63,7 +77,22 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
         }
     }
 
-    if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
+    switch (vsew) {
+    case MO_8:
+        ill_altfmt &= !(cpu->cfg.ext_zvfbfa);
+        break;
+    case MO_16:
+        ill_altfmt &= !(cpu->cfg.ext_zvfbfa);
+        break;
+    default:
+        break;
+    }
+
+    if (altfmt && ill_altfmt) {
+        vill = true;
+    }
+
+    if ((sew > cpu->cfg.elen) || vill || (vtype_reserved(env, s2) != 0)) {
         /* only set vill bit. */
         env->vill = 1;
         env->vtype = 0;
-- 
2.52.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v5 4/9] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR
  2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
                   ` (2 preceding siblings ...)
  2026-03-06  7:10 ` [PATCH v5 3/9] target/riscv: rvv: Add new VTYPE CSR field - altfmt Max Chou
@ 2026-03-06  7:10 ` Max Chou
  2026-03-09  4:55   ` Alistair Francis
  2026-03-16  9:22   ` Nutty.Liu
  2026-03-06  7:11 ` [PATCH v5 5/9] target/riscv: Use the tb->cs_base as the extend tb flags Max Chou
                   ` (5 subsequent siblings)
  9 siblings, 2 replies; 28+ messages in thread
From: Max Chou @ 2026-03-06  7:10 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Chou

Replace the same vill reset flow by reset_ill_vtype function.

Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
---
 target/riscv/vector_helper.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 7575e24084..b7105627ed 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -49,6 +49,15 @@ static target_ulong vtype_reserved(CPURISCVState *env, target_ulong vtype)
     return reserved;
 }
 
+static inline void reset_ill_vtype(CPURISCVState *env)
+{
+    /* only set vill bit. */
+    env->vill = 1;
+    env->vtype = 0;
+    env->vl = 0;
+    env->vstart = 0;
+}
+
 target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
                             target_ulong s2, target_ulong x0)
 {
@@ -93,11 +102,7 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
     }
 
     if ((sew > cpu->cfg.elen) || vill || (vtype_reserved(env, s2) != 0)) {
-        /* only set vill bit. */
-        env->vill = 1;
-        env->vtype = 0;
-        env->vl = 0;
-        env->vstart = 0;
+        reset_ill_vtype(env);
         return 0;
     }
 
@@ -113,11 +118,7 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
     }
 
     if (cpu->cfg.rvv_vsetvl_x0_vill && x0 && (env->vl != vl)) {
-        /* only set vill bit. */
-        env->vill = 1;
-        env->vtype = 0;
-        env->vl = 0;
-        env->vstart = 0;
+        reset_ill_vtype(env);
         return 0;
     }
 
-- 
2.52.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v5 5/9] target/riscv: Use the tb->cs_base as the extend tb flags
  2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
                   ` (3 preceding siblings ...)
  2026-03-06  7:10 ` [PATCH v5 4/9] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR Max Chou
@ 2026-03-06  7:11 ` Max Chou
  2026-03-09  5:01   ` Alistair Francis
  2026-03-06  7:11 ` [PATCH v5 6/9] target/riscv: Introduce altfmt into DisasContext Max Chou
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Max Chou @ 2026-03-06  7:11 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Chou

We have more than 32-bits worth of state per TB, so use the
tb->cs_base, which is otherwise unused for RISC-V, as the extend flag.

Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
---
 include/exec/translation-block.h | 1 +
 target/riscv/cpu.h               | 3 +++
 target/riscv/tcg/tcg-cpu.c       | 7 ++++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h
index 4f83d5bec9..40cc699031 100644
--- a/include/exec/translation-block.h
+++ b/include/exec/translation-block.h
@@ -65,6 +65,7 @@ struct TranslationBlock {
      * arm: an extension of tb->flags,
      * s390x: instruction data for EXECUTE,
      * sparc: the next pc of the instruction queue (for delay slots).
+     * riscv: an extension of tb->flags,
      */
     uint64_t cs_base;
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 962cc45073..4c0676ed53 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -703,6 +703,9 @@ FIELD(TB_FLAGS, BCFI_ENABLED, 28, 1)
 FIELD(TB_FLAGS, PM_PMM, 29, 2)
 FIELD(TB_FLAGS, PM_SIGNEXTEND, 31, 1)
 
+FIELD(EXT_TB_FLAGS, MISA_EXT, 0, 32)
+FIELD(EXT_TB_FLAGS, ALTFMT, 32, 1)
+
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
 #else
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 720ff0c2a3..378b298886 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -104,6 +104,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
     RISCVCPU *cpu = env_archcpu(env);
     RISCVExtStatus fs, vs;
     uint32_t flags = 0;
+    uint64_t ext_flags = 0;
     bool pm_signext = riscv_cpu_virt_mem_enabled(env);
 
     if (cpu->cfg.ext_zve32x) {
@@ -118,6 +119,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
 
         /* lmul encoded as in DisasContext::lmul */
         int8_t lmul = sextract32(FIELD_EX64(env->vtype, VTYPE, VLMUL), 0, 3);
+        uint8_t altfmt = FIELD_EX64(env->vtype, VTYPE, ALTFMT);
         uint32_t vsew = FIELD_EX64(env->vtype, VTYPE, VSEW);
         uint32_t vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul);
         uint32_t maxsz = vlmax << vsew;
@@ -133,6 +135,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
         flags = FIELD_DP32(flags, TB_FLAGS, VMA,
                            FIELD_EX64(env->vtype, VTYPE, VMA));
         flags = FIELD_DP32(flags, TB_FLAGS, VSTART_EQ_ZERO, env->vstart == 0);
+        ext_flags = FIELD_DP64(ext_flags, EXT_TB_FLAGS, ALTFMT, altfmt);
     } else {
         flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
     }
@@ -189,10 +192,12 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
     flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env));
     flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext);
 
+    ext_flags = FIELD_DP64(ext_flags, EXT_TB_FLAGS, MISA_EXT, env->misa_ext);
+
     return (TCGTBCPUState){
         .pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc,
         .flags = flags,
-        .cs_base = env->misa_ext,
+        .cs_base = ext_flags,
     };
 }
 
-- 
2.52.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v5 6/9] target/riscv: Introduce altfmt into DisasContext
  2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
                   ` (4 preceding siblings ...)
  2026-03-06  7:11 ` [PATCH v5 5/9] target/riscv: Use the tb->cs_base as the extend tb flags Max Chou
@ 2026-03-06  7:11 ` Max Chou
  2026-03-09  5:02   ` Alistair Francis
  2026-03-06  7:11 ` [PATCH v5 7/9] target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension Max Chou
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Max Chou @ 2026-03-06  7:11 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Chou

Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
---
 target/riscv/translate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index cb4f443601..89d4f6fe67 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -101,6 +101,7 @@ typedef struct DisasContext {
     bool cfg_vta_all_1s;
     bool vstart_eq_zero;
     bool vl_eq_vlmax;
+    bool altfmt;
     CPUState *cs;
     TCGv zero;
     /* actual address width */
@@ -1307,6 +1308,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
     RISCVCPU *cpu = RISCV_CPU(cs);
     uint32_t tb_flags = ctx->base.tb->flags;
+    uint64_t ext_tb_flags = ctx->base.tb->cs_base;
 
     ctx->pc_save = ctx->base.pc_first;
     ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
@@ -1326,6 +1328,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
     ctx->vstart_eq_zero = FIELD_EX32(tb_flags, TB_FLAGS, VSTART_EQ_ZERO);
     ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
+    ctx->altfmt = FIELD_EX64(ext_tb_flags, EXT_TB_FLAGS, ALTFMT);
     ctx->misa_mxl_max = mcc->def->misa_mxl_max;
     ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
     ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
-- 
2.52.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v5 7/9] target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension
  2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
                   ` (5 preceding siblings ...)
  2026-03-06  7:11 ` [PATCH v5 6/9] target/riscv: Introduce altfmt into DisasContext Max Chou
@ 2026-03-06  7:11 ` Max Chou
  2026-03-09  5:04   ` Alistair Francis
  2026-03-06  7:11 ` [PATCH v5 8/9] target/riscv: rvv: Support Zvfbfa vector bf16 operations Max Chou
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 28+ messages in thread
From: Max Chou @ 2026-03-06  7:11 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Chou

According to the Zvfbfa ISA spec (v0.1), improperly NaN-boxed
f-register operands must substitute the BF16 canonical NaN instead of
the FP16 canonical NaN for some vector floating-point instructions.

Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
---
 target/riscv/insn_trans/trans_rvv.c.inc | 18 +++++++++---------
 target/riscv/translate.c                |  8 ++++++++
 2 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 4df9a40b44..03ae85796a 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2319,17 +2319,17 @@ GEN_OPIWI_NARROW_TRANS(vnclip_wi, IMM_ZX, vnclip_wx)
  */
 static void do_nanbox(DisasContext *s, TCGv_i64 out, TCGv_i64 in)
 {
-    switch (s->sew) {
-    case 1:
-        gen_check_nanbox_h(out, in);
-        break;
-    case 2:
+    if (s->sew == MO_16) {
+        if (s->altfmt) {
+            gen_check_nanbox_h_bf16(out, in);
+        } else {
+            gen_check_nanbox_h(out, in);
+        }
+    } else if (s->sew == MO_32) {
         gen_check_nanbox_s(out, in);
-        break;
-    case 3:
+    } else if (s->sew == MO_64) {
         tcg_gen_mov_i64(out, in);
-        break;
-    default:
+    } else {
         g_assert_not_reached();
     }
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 89d4f6fe67..d9df6a35ca 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -214,6 +214,14 @@ static void gen_check_nanbox_h(TCGv_i64 out, TCGv_i64 in)
     tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
 }
 
+static void gen_check_nanbox_h_bf16(TCGv_i64 out, TCGv_i64 in)
+{
+    TCGv_i64 t_max = tcg_constant_i64(0xffffffffffff0000ull);
+    TCGv_i64 t_nan = tcg_constant_i64(0xffffffffffff7fc0ull);
+
+    tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
+}
+
 static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
 {
     TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull);
-- 
2.52.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v5 8/9] target/riscv: rvv: Support Zvfbfa vector bf16 operations
  2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
                   ` (6 preceding siblings ...)
  2026-03-06  7:11 ` [PATCH v5 7/9] target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension Max Chou
@ 2026-03-06  7:11 ` Max Chou
  2026-03-06  7:11 ` [PATCH v5 9/9] target/riscv: Expose Zvfbfa extension as an experimental cpu property Max Chou
  2026-03-09  4:51 ` [PATCH v5 0/9] Add Zvfbfa extension support Alistair Francis
  9 siblings, 0 replies; 28+ messages in thread
From: Max Chou @ 2026-03-06  7:11 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Chou

According to the Zvfbfa ISA spec v0.1, the following vector floating
point instructions have different behaviors depend on the ALTFMT and
VSEW fields of VTYPE CSR.

When altfmt=1 and SEW=8, all vector floating-point instructions become
reserved, except for the following, which are redefined to use the
BF16 format for any operand that would otherwise have used the FP16
format:
- vfwcvt.f.x[u].v, vfncvt.x[u].f.w, vfncvt.rtz.x[u].f.w

When altfmt=1 and SEW=16, all vector floating-point instructions become
reserved, except for the following, which are redefined to use the
BF16 format for any operand that would otherwise have used the FP16
format:
- vfadd.v[vf], vfsub.v[vf], vfmin.v[vf], vfmax.v[vf], vmfeq.v[vf],
  vmfle.v[vf], vmflt.v[vf], vmfne.v[vf], vmfgt.vf, vmfge.vf,
  vfmul.v[vf], vfrsub.vf, vfmadd.v[vf], vfnmadd.v[vf], vfmsub.v[vf],
  vfnmsub.v[vf], vfmacc.v[vf], vfnmacc.v[vf], vfmsac.v[vf],
  vfnmsac.v[vf], vfwadd.v[vf], vfwsub.v[vf], vfwadd.w[vf],
  vfwsub.w[vf], vfwmul.v[vf], vfwmacc.v[vf], vfwnmacc.v[vf],
  vfwmsac.v[vf], vfwnmsac.v[vf], vfwcvt.f.f.v, vfncvt.f.f.w,
  vfncvt.rod.f.f.w, vfrsqrt7.v, vfrec7.v, vfclass.v

The following instructions marked with * have the same semantics
regardless of altfmt.
*- vfmv.f.s,
   vfwmaccbf16.v[vf] (only if Zvfbfwma is implemented)
   vfwcvtbf16.f.f.v (only if Zvfbfmin is implemented)
   vfncvtbf16.f.f.w (only if Zvfbfmin is implemented)

The following instructions marked with ** differ only in that
improperly NaN-boxed f-register operands must substitute the BF16
canonical NaN instead of the FP16 canonical NaN.
**- vfsgnj.v[vf], vfsgnjn.v[vf], vfsgnjx.v[vf], vfslide1up.vf,
    vfslide1down.vf, vfmv.v.f, vfmerge.vfm, vfmv.s.f

Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
---
 target/riscv/helper.h                   |  60 ++
 target/riscv/insn_trans/trans_rvv.c.inc | 970 +++++++++++++++---------
 target/riscv/internals.h                |   1 +
 target/riscv/vector_helper.c            | 329 ++++++++
 4 files changed, 989 insertions(+), 371 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index b785456ee0..eb0a488ba8 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -766,45 +766,60 @@ DEF_HELPER_6(vnclip_wx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vnclip_wx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vnclip_wx_w, void, ptr, ptr, tl, ptr, env, i32)
 
+DEF_HELPER_6(vfadd_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfsub_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfadd_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfadd_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfsub_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfrsub_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfrsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfrsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfrsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
 
+DEF_HELPER_6(vfwadd_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwsub_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwadd_wv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwadd_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwadd_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwsub_wv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwsub_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwsub_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwadd_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwsub_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwadd_wf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwadd_wf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwadd_wf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwsub_wf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwsub_wf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwsub_wf_w, void, ptr, ptr, i64, ptr, env, i32)
 
+DEF_HELPER_6(vfmul_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmul_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfdiv_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfdiv_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfdiv_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmul_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmul_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmul_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmul_vf_d, void, ptr, ptr, i64, ptr, env, i32)
@@ -815,74 +830,98 @@ DEF_HELPER_6(vfrdiv_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfrdiv_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfrdiv_vf_d, void, ptr, ptr, i64, ptr, env, i32)
 
+DEF_HELPER_6(vfwmul_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwmul_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwmul_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwmul_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 
+DEF_HELPER_6(vfmacc_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmacc_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfnmacc_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmacc_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmsac_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmsac_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfnmsac_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmsac_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmadd_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfnmadd_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmsub_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfnmsub_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfnmsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmacc_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmacc_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfnmacc_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmacc_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmsac_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmsac_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfnmsac_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmsac_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmadd_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmadd_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfnmadd_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmadd_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmsub_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfnmsub_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfnmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
 
 DEF_HELPER_6(vfwmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwnmacc_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwnmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwnmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwmsac_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfwnmsac_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwnmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwnmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfwmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwnmacc_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwnmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwnmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwmsac_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfwnmsac_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwnmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfwnmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 
@@ -890,23 +929,29 @@ DEF_HELPER_5(vfsqrt_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfsqrt_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfsqrt_v_d, void, ptr, ptr, ptr, env, i32)
 
+DEF_HELPER_5(vfrsqrt7_v_h_bf16, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfrsqrt7_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfrsqrt7_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfrsqrt7_v_d, void, ptr, ptr, ptr, env, i32)
 
+DEF_HELPER_5(vfrec7_v_h_bf16, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfrec7_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfrec7_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfrec7_v_d, void, ptr, ptr, ptr, env, i32)
 
+DEF_HELPER_6(vfmin_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmin_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmin_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmin_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmax_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmax_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmax_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmax_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vfmin_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmin_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmin_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmin_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfmax_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmax_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmax_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfmax_vf_d, void, ptr, ptr, i64, ptr, env, i32)
@@ -930,37 +975,48 @@ DEF_HELPER_6(vfsgnjx_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfsgnjx_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vfsgnjx_vf_d, void, ptr, ptr, i64, ptr, env, i32)
 
+DEF_HELPER_6(vmfeq_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmfeq_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmfeq_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmfeq_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfne_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmfne_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmfne_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmfne_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmflt_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmflt_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmflt_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmflt_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfle_vv_h_bf16, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmfle_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmfle_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmfle_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmfeq_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfeq_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfeq_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfeq_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfne_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfne_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfne_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfne_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmflt_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmflt_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmflt_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmflt_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfle_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfle_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfle_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfle_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfgt_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfgt_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfgt_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfgt_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vmfge_vf_h_bf16, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfge_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfge_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfge_vf_d, void, ptr, ptr, i64, ptr, env, i32)
 
+DEF_HELPER_5(vfclass_v_h_bf16, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfclass_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfclass_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfclass_v_d, void, ptr, ptr, ptr, env, i32)
@@ -987,18 +1043,22 @@ DEF_HELPER_5(vfwcvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_xu_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_xu_v_b_bf16, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_x_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_x_v_b_bf16, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_5(vfncvt_xu_f_w_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_xu_f_w_b_bf16, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfncvt_xu_f_w_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfncvt_xu_f_w_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfncvt_x_f_w_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_x_f_w_b_bf16, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfncvt_x_f_w_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfncvt_x_f_w_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfncvt_f_xu_w_h, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 03ae85796a..5b72926b3c 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -40,6 +40,9 @@ static bool require_rvf(DisasContext *s)
 
     switch (s->sew) {
     case MO_16:
+        if (s->altfmt) {
+            return s->cfg_ptr->ext_zvfbfa;
+        }
         return s->cfg_ptr->ext_zvfh;
     case MO_32:
         return s->cfg_ptr->ext_zve32f;
@@ -58,6 +61,9 @@ static bool require_rvfmin(DisasContext *s)
 
     switch (s->sew) {
     case MO_16:
+        if (s->altfmt) {
+            return s->cfg_ptr->ext_zvfbfa;
+        }
         return s->cfg_ptr->ext_zvfhmin;
     case MO_32:
         return s->cfg_ptr->ext_zve32f;
@@ -74,6 +80,9 @@ static bool require_scale_rvf(DisasContext *s)
 
     switch (s->sew) {
     case MO_8:
+        if (s->altfmt) {
+            return s->cfg_ptr->ext_zvfbfa;
+        }
         return s->cfg_ptr->ext_zvfh;
     case MO_16:
         return s->cfg_ptr->ext_zve32f;
@@ -2334,25 +2343,39 @@ static void do_nanbox(DisasContext *s, TCGv_i64 out, TCGv_i64 in)
     }
 }
 
+/*
+ * Check altfmt & sew combinations when Zvfbfa extension is enabled.
+ */
+static bool vext_check_altfmt(DisasContext *s, int8_t valid_vsew)
+{
+    if (s->cfg_ptr->ext_zvfbfa) {
+        if (s->altfmt && (valid_vsew == -1 || s->sew != valid_vsew)) {
+            return false;
+        }
+    }
+    return true;
+}
+
 /* Vector Single-Width Floating-Point Add/Subtract Instructions */
 
 /*
  * If the current SEW does not correspond to a supported IEEE floating-point
  * type, an illegal instruction exception is raised.
  */
-static bool opfvv_check(DisasContext *s, arg_rmrr *a)
+static bool opfvv_check(DisasContext *s, arg_rmrr *a, int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_rvf(s) &&
            vext_check_isa_ill(s) &&
-           vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
+           vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
 /* OPFVV without GVEC IR */
 #define GEN_OPFVV_TRANS(NAME, CHECK)                               \
 static bool trans_##NAME(DisasContext *s, arg_rmrr *a)             \
 {                                                                  \
-    if (CHECK(s, a)) {                                             \
+    if (CHECK(s, a, -1)) {                                         \
         uint32_t data = 0;                                         \
         static gen_helper_gvec_4_ptr * const fns[3] = {            \
             gen_helper_##NAME##_h,                                 \
@@ -2378,8 +2401,41 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)             \
     }                                                              \
     return false;                                                  \
 }
-GEN_OPFVV_TRANS(vfadd_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfsub_vv, opfvv_check)
+
+#define GEN_OPFVV_BFA_TRANS(NAME, CHECK, BFA_HELPER)                    \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                  \
+{                                                                       \
+    if (CHECK(s, a, MO_16)) {                                           \
+        uint32_t data = 0;                                              \
+        static gen_helper_gvec_4_ptr * const fns[3] = {                 \
+            gen_helper_##NAME##_h,                                      \
+            gen_helper_##NAME##_w,                                      \
+            gen_helper_##NAME##_d                                       \
+        };                                                              \
+        gen_set_rm(s, RISCV_FRM_DYN);                                   \
+                                                                        \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);                      \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                  \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);                    \
+        data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);  \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);                    \
+        tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),          \
+                           vreg_ofs(s, a->rs1),                         \
+                           vreg_ofs(s, a->rs2), tcg_env,                \
+                           s->cfg_ptr->vlenb,                           \
+                           s->cfg_ptr->vlenb, data,                     \
+                           (s->altfmt ? gen_helper_##BFA_HELPER :       \
+                                        fns[s->sew - 1]));              \
+        tcg_gen_movi_tl(cpu_vstart, 0);                                 \
+        finalize_rvv_inst(s);                                           \
+                                                                        \
+        return true;                                                    \
+    }                                                                   \
+    return false;                                                       \
+}
+
+GEN_OPFVV_BFA_TRANS(vfadd_vv, opfvv_check, vfadd_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfsub_vv, opfvv_check, vfsub_vv_h_bf16)
 
 typedef void gen_helper_opfvf(TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_ptr,
                               TCGv_env, TCGv_i32);
@@ -2415,244 +2471,316 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
  * If the current SEW does not correspond to a supported IEEE floating-point
  * type, an illegal instruction exception is raised
  */
-static bool opfvf_check(DisasContext *s, arg_rmrr *a)
+static bool opfvf_check(DisasContext *s, arg_rmrr *a, int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_rvf(s) &&
            vext_check_isa_ill(s) &&
-           vext_check_ss(s, a->rd, a->rs2, a->vm);
+           vext_check_ss(s, a->rd, a->rs2, a->vm) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
 /* OPFVF without GVEC IR */
-#define GEN_OPFVF_TRANS(NAME, CHECK)                              \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a)            \
-{                                                                 \
-    if (CHECK(s, a)) {                                            \
-        uint32_t data = 0;                                        \
-        static gen_helper_opfvf *const fns[3] = {                 \
-            gen_helper_##NAME##_h,                                \
-            gen_helper_##NAME##_w,                                \
-            gen_helper_##NAME##_d,                                \
-        };                                                        \
-        gen_set_rm(s, RISCV_FRM_DYN);                             \
-        data = FIELD_DP32(data, VDATA, VM, a->vm);                \
-        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);            \
-        data = FIELD_DP32(data, VDATA, VTA, s->vta);              \
-        data = FIELD_DP32(data, VDATA, VTA_ALL_1S,                \
-                          s->cfg_vta_all_1s);                     \
-        data = FIELD_DP32(data, VDATA, VMA, s->vma);              \
-        return opfvf_trans(a->rd, a->rs1, a->rs2, data,           \
-                           fns[s->sew - 1], s);                   \
-    }                                                             \
-    return false;                                                 \
-}
-
-GEN_OPFVF_TRANS(vfadd_vf,  opfvf_check)
-GEN_OPFVF_TRANS(vfsub_vf,  opfvf_check)
-GEN_OPFVF_TRANS(vfrsub_vf,  opfvf_check)
+#define GEN_OPFVF_TRANS(NAME, CHECK)                    \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)  \
+{                                                       \
+    if (CHECK(s, a, -1)) {                              \
+        uint32_t data = 0;                              \
+        static gen_helper_opfvf *const fns[3] = {       \
+            gen_helper_##NAME##_h,                      \
+            gen_helper_##NAME##_w,                      \
+            gen_helper_##NAME##_d,                      \
+        };                                              \
+        gen_set_rm(s, RISCV_FRM_DYN);                   \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);      \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);  \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);    \
+        data = FIELD_DP32(data, VDATA, VTA_ALL_1S,      \
+                          s->cfg_vta_all_1s);           \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);    \
+        return opfvf_trans(a->rd, a->rs1, a->rs2, data, \
+                           fns[s->sew - 1], s);         \
+    }                                                   \
+    return false;                                       \
+}
+
+#define GEN_OPFVF_BFA_TRANS(NAME, CHECK, BFA_HELPER)                \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)              \
+{                                                                   \
+    if (CHECK(s, a, MO_16)) {                                       \
+        uint32_t data = 0;                                          \
+        static gen_helper_opfvf *const fns[3] = {                   \
+            gen_helper_##NAME##_h,                                  \
+            gen_helper_##NAME##_w,                                  \
+            gen_helper_##NAME##_d,                                  \
+        };                                                          \
+        gen_set_rm(s, RISCV_FRM_DYN);                               \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);                  \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);              \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);                \
+        data = FIELD_DP32(data, VDATA, VTA_ALL_1S,                  \
+                          s->cfg_vta_all_1s);                       \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);                \
+        return opfvf_trans(a->rd, a->rs1, a->rs2, data,             \
+                           (s->altfmt ? gen_helper_##BFA_HELPER :   \
+                                        fns[s->sew - 1]),           \
+                           s);                                      \
+    }                                                               \
+    return false;                                                   \
+}
+
+GEN_OPFVF_BFA_TRANS(vfadd_vf,  opfvf_check, vfadd_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfsub_vf,  opfvf_check, vfsub_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfrsub_vf,  opfvf_check, vfrsub_vf_h_bf16)
 
 /* Vector Widening Floating-Point Add/Subtract Instructions */
-static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
+static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a,
+                              int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_rvf(s) &&
            require_scale_rvf(s) &&
            vext_check_isa_ill(s) &&
-           vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
+           vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-static bool opfvv_overwrite_widen_check(DisasContext *s, arg_rmrr *a)
+static bool opfvv_overwrite_widen_check(DisasContext *s, arg_rmrr *a,
+                                        int8_t valid_bfa_vsew)
 {
-    return require_rvv(s) &&
-           require_rvf(s) &&
-           require_scale_rvf(s) &&
-           vext_check_isa_ill(s) &&
-           vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm) &&
+    return opfvv_widen_check(s, a, valid_bfa_vsew) &&
            vext_check_input_eew(s, a->rd, s->sew + 1, a->rs1, s->sew, a->vm) &&
            vext_check_input_eew(s, a->rd, s->sew + 1, a->rs2, s->sew, a->vm);
 }
 
 /* OPFVV with WIDEN */
-#define GEN_OPFVV_WIDEN_TRANS(NAME, CHECK)                       \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a)           \
-{                                                                \
-    if (CHECK(s, a)) {                                           \
-        uint32_t data = 0;                                       \
-        static gen_helper_gvec_4_ptr * const fns[2] = {          \
-            gen_helper_##NAME##_h, gen_helper_##NAME##_w,        \
-        };                                                       \
-        gen_set_rm(s, RISCV_FRM_DYN);                            \
-                                                                 \
-        data = FIELD_DP32(data, VDATA, VM, a->vm);               \
-        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);           \
-        data = FIELD_DP32(data, VDATA, VTA, s->vta);             \
-        data = FIELD_DP32(data, VDATA, VMA, s->vma);             \
-        tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),   \
-                           vreg_ofs(s, a->rs1),                  \
-                           vreg_ofs(s, a->rs2), tcg_env,         \
-                           s->cfg_ptr->vlenb,                    \
-                           s->cfg_ptr->vlenb, data,              \
-                           fns[s->sew - 1]);                     \
-        finalize_rvv_inst(s);                                    \
-        return true;                                             \
-    }                                                            \
-    return false;                                                \
-}
-
-GEN_OPFVV_WIDEN_TRANS(vfwadd_vv, opfvv_widen_check)
-GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
-
-static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
+#define GEN_OPFVV_WIDEN_TRANS(NAME, CHECK)                      \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)          \
+{                                                               \
+    if (CHECK(s, a, -1)) {                                      \
+        uint32_t data = 0;                                      \
+        static gen_helper_gvec_4_ptr * const fns[2] = {         \
+            gen_helper_##NAME##_h, gen_helper_##NAME##_w,       \
+        };                                                      \
+        gen_set_rm(s, RISCV_FRM_DYN);                           \
+                                                                \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);              \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);          \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);            \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);            \
+        tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),  \
+                           vreg_ofs(s, a->rs1),                 \
+                           vreg_ofs(s, a->rs2), tcg_env,        \
+                           s->cfg_ptr->vlenb,                   \
+                           s->cfg_ptr->vlenb, data,             \
+                           fns[s->sew - 1]);                    \
+        finalize_rvv_inst(s);                                   \
+        return true;                                            \
+    }                                                           \
+    return false;                                               \
+}
+
+#define GEN_OPFVV_WIDEN_BFA_TRANS(NAME, CHECK, BFA_HELPER)          \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)              \
+{                                                                   \
+    if (CHECK(s, a, MO_16)) {                                       \
+        uint32_t data = 0;                                          \
+        static gen_helper_gvec_4_ptr * const fns[2] = {             \
+            gen_helper_##NAME##_h,                                  \
+            gen_helper_##NAME##_w                                   \
+        };                                                          \
+        gen_set_rm(s, RISCV_FRM_DYN);                               \
+                                                                    \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);                  \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);              \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);                \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);                \
+        tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),      \
+                           vreg_ofs(s, a->rs1),                     \
+                           vreg_ofs(s, a->rs2), tcg_env,            \
+                           s->cfg_ptr->vlenb,                       \
+                           s->cfg_ptr->vlenb, data,                 \
+                           (s->altfmt ? gen_helper_##BFA_HELPER :   \
+                                        fns[s->sew - 1]));          \
+        finalize_rvv_inst(s);                                       \
+        return true;                                                \
+    }                                                               \
+    return false;                                                   \
+}
+
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwadd_vv, opfvv_widen_check, vfwadd_vv_h_bf16)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwsub_vv, opfvv_widen_check, vfwsub_vv_h_bf16)
+
+static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a,
+                              int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_rvf(s) &&
            require_scale_rvf(s) &&
            vext_check_isa_ill(s) &&
-           vext_check_ds(s, a->rd, a->rs2, a->vm);
+           vext_check_ds(s, a->rd, a->rs2, a->vm) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-static bool opfvf_overwrite_widen_check(DisasContext *s, arg_rmrr *a)
+static bool opfvf_overwrite_widen_check(DisasContext *s, arg_rmrr *a,
+                                        int8_t valid_bfa_vsew)
 {
-    return require_rvv(s) &&
-           require_rvf(s) &&
-           require_scale_rvf(s) &&
-           vext_check_isa_ill(s) &&
-           vext_check_ds(s, a->rd, a->rs2, a->vm) &&
+    return opfvf_widen_check(s, a, valid_bfa_vsew) &&
            vext_check_input_eew(s, a->rd, s->sew + 1, a->rs2, s->sew, a->vm);
 }
 
 /* OPFVF with WIDEN */
-#define GEN_OPFVF_WIDEN_TRANS(NAME, CHECK)                       \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a)           \
-{                                                                \
-    if (CHECK(s, a)) {                                           \
-        uint32_t data = 0;                                       \
-        static gen_helper_opfvf *const fns[2] = {                \
-            gen_helper_##NAME##_h, gen_helper_##NAME##_w,        \
-        };                                                       \
-        gen_set_rm(s, RISCV_FRM_DYN);                            \
-        data = FIELD_DP32(data, VDATA, VM, a->vm);               \
-        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);           \
-        data = FIELD_DP32(data, VDATA, VTA, s->vta);             \
-        data = FIELD_DP32(data, VDATA, VMA, s->vma);             \
-        return opfvf_trans(a->rd, a->rs1, a->rs2, data,          \
-                           fns[s->sew - 1], s);                  \
-    }                                                            \
-    return false;                                                \
-}
-
-GEN_OPFVF_WIDEN_TRANS(vfwadd_vf, opfvf_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwsub_vf, opfvf_widen_check)
-
-static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
+#define GEN_OPFVF_WIDEN_BFA_TRANS(NAME, CHECK, BFA_HELPER)          \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)              \
+{                                                                   \
+    if (CHECK(s, a, MO_16)) {                                       \
+        uint32_t data = 0;                                          \
+        static gen_helper_opfvf *const fns[2] = {                   \
+            gen_helper_##NAME##_h,                                  \
+            gen_helper_##NAME##_w,                                  \
+        };                                                          \
+        gen_set_rm(s, RISCV_FRM_DYN);                               \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);                  \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);              \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);                \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);                \
+        return opfvf_trans(a->rd, a->rs1, a->rs2, data,             \
+                           (s->altfmt ? gen_helper_##BFA_HELPER :   \
+                                        fns[s->sew - 1]),           \
+                           s);                                      \
+    }                                                               \
+    return false;                                                   \
+}
+
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwadd_vf, opfvf_widen_check, vfwadd_vf_h_bf16)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwsub_vf, opfvf_widen_check, vfwsub_vf_h_bf16)
+
+static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a,
+                              int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_rvf(s) &&
            require_scale_rvf(s) &&
            vext_check_isa_ill(s) &&
-           vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
+           vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
 /* WIDEN OPFVV with WIDEN */
-#define GEN_OPFWV_WIDEN_TRANS(NAME)                                \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a)             \
-{                                                                  \
-    if (opfwv_widen_check(s, a)) {                                 \
-        uint32_t data = 0;                                         \
-        static gen_helper_gvec_4_ptr * const fns[2] = {            \
-            gen_helper_##NAME##_h, gen_helper_##NAME##_w,          \
-        };                                                         \
-        gen_set_rm(s, RISCV_FRM_DYN);                              \
-                                                                   \
-        data = FIELD_DP32(data, VDATA, VM, a->vm);                 \
-        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);             \
-        data = FIELD_DP32(data, VDATA, VTA, s->vta);               \
-        data = FIELD_DP32(data, VDATA, VMA, s->vma);               \
-        tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),     \
-                           vreg_ofs(s, a->rs1),                    \
-                           vreg_ofs(s, a->rs2), tcg_env,           \
-                           s->cfg_ptr->vlenb,                      \
-                           s->cfg_ptr->vlenb, data,                \
-                           fns[s->sew - 1]);                       \
-        finalize_rvv_inst(s);                                      \
-        return true;                                               \
-    }                                                              \
-    return false;                                                  \
+#define GEN_OPFWV_WIDEN_BFA_TRANS(NAME)                                 \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                  \
+{                                                                       \
+    if (opfwv_widen_check(s, a, MO_16)) {                               \
+        uint32_t data = 0;                                              \
+        static gen_helper_gvec_4_ptr * const fns[2] = {                 \
+            gen_helper_##NAME##_h,                                      \
+            gen_helper_##NAME##_w                                       \
+        };                                                              \
+        gen_set_rm(s, RISCV_FRM_DYN);                                   \
+                                                                        \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);                      \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                  \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);                    \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);                    \
+        tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),          \
+                           vreg_ofs(s, a->rs1),                         \
+                           vreg_ofs(s, a->rs2), tcg_env,                \
+                           s->cfg_ptr->vlenb,                           \
+                           s->cfg_ptr->vlenb, data,                     \
+                           (s->altfmt ? gen_helper_##NAME##_h_bf16 :    \
+                                        fns[s->sew - 1]));              \
+        finalize_rvv_inst(s);                                           \
+        return true;                                                    \
+    }                                                                   \
+    return false;                                                       \
 }
 
-GEN_OPFWV_WIDEN_TRANS(vfwadd_wv)
-GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
+GEN_OPFWV_WIDEN_BFA_TRANS(vfwadd_wv)
+GEN_OPFWV_WIDEN_BFA_TRANS(vfwsub_wv)
 
-static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
+static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a,
+                              int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_rvf(s) &&
            require_scale_rvf(s) &&
            vext_check_isa_ill(s) &&
-           vext_check_dd(s, a->rd, a->rs2, a->vm);
+           vext_check_dd(s, a->rd, a->rs2, a->vm) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
 /* WIDEN OPFVF with WIDEN */
-#define GEN_OPFWF_WIDEN_TRANS(NAME)                              \
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a)           \
-{                                                                \
-    if (opfwf_widen_check(s, a)) {                               \
-        uint32_t data = 0;                                       \
-        static gen_helper_opfvf *const fns[2] = {                \
-            gen_helper_##NAME##_h, gen_helper_##NAME##_w,        \
-        };                                                       \
-        gen_set_rm(s, RISCV_FRM_DYN);                            \
-        data = FIELD_DP32(data, VDATA, VM, a->vm);               \
-        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);           \
-        data = FIELD_DP32(data, VDATA, VTA, s->vta);             \
-        data = FIELD_DP32(data, VDATA, VMA, s->vma);             \
-        return opfvf_trans(a->rd, a->rs1, a->rs2, data,          \
-                           fns[s->sew - 1], s);                  \
-    }                                                            \
-    return false;                                                \
-}
-
-GEN_OPFWF_WIDEN_TRANS(vfwadd_wf)
-GEN_OPFWF_WIDEN_TRANS(vfwsub_wf)
+#define GEN_OPFWF_WIDEN_BFA_TRANS(NAME)                                 \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                  \
+{                                                                       \
+    if (opfwf_widen_check(s, a, MO_16)) {                               \
+        uint32_t data = 0;                                              \
+        static gen_helper_opfvf *const fns[2] = {                       \
+            gen_helper_##NAME##_h,                                      \
+            gen_helper_##NAME##_w                                       \
+        };                                                              \
+        gen_set_rm(s, RISCV_FRM_DYN);                                   \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);                      \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                  \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);                    \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);                    \
+        return opfvf_trans(a->rd, a->rs1, a->rs2, data,                 \
+                           (s->altfmt ? gen_helper_##NAME##_h_bf16 :    \
+                                        fns[s->sew - 1]),               \
+                           s);                                          \
+    }                                                                   \
+    return false;                                                       \
+}
+
+GEN_OPFWF_WIDEN_BFA_TRANS(vfwadd_wf)
+GEN_OPFWF_WIDEN_BFA_TRANS(vfwsub_wf)
 
 /* Vector Single-Width Floating-Point Multiply/Divide Instructions */
-GEN_OPFVV_TRANS(vfmul_vv, opfvv_check)
+GEN_OPFVV_BFA_TRANS(vfmul_vv, opfvv_check, vfmul_vv_h_bf16)
 GEN_OPFVV_TRANS(vfdiv_vv, opfvv_check)
-GEN_OPFVF_TRANS(vfmul_vf,  opfvf_check)
+GEN_OPFVF_BFA_TRANS(vfmul_vf,  opfvf_check, vfmul_vf_h_bf16)
 GEN_OPFVF_TRANS(vfdiv_vf,  opfvf_check)
 GEN_OPFVF_TRANS(vfrdiv_vf,  opfvf_check)
 
 /* Vector Widening Floating-Point Multiply */
-GEN_OPFVV_WIDEN_TRANS(vfwmul_vv, opfvv_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwmul_vf, opfvf_widen_check)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwmul_vv, opfvv_widen_check, vfwmul_vv_h_bf16)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwmul_vf, opfvf_widen_check, vfwmul_vf_h_bf16)
 
 /* Vector Single-Width Floating-Point Fused Multiply-Add Instructions */
-GEN_OPFVV_TRANS(vfmacc_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfnmacc_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfmsac_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfnmsac_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfmadd_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfnmadd_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfmsub_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfnmsub_vv, opfvv_check)
-GEN_OPFVF_TRANS(vfmacc_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfnmacc_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfmsac_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfnmsac_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfmadd_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfnmadd_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfmsub_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfnmsub_vf, opfvf_check)
+GEN_OPFVV_BFA_TRANS(vfmacc_vv, opfvv_check, vfmacc_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfnmacc_vv, opfvv_check, vfnmacc_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfmsac_vv, opfvv_check, vfmsac_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfnmsac_vv, opfvv_check, vfnmsac_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfmadd_vv, opfvv_check, vfmadd_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfnmadd_vv, opfvv_check, vfnmadd_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfmsub_vv, opfvv_check, vfmsub_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfnmsub_vv, opfvv_check, vfnmsub_vv_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmacc_vf, opfvf_check, vfmacc_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfnmacc_vf, opfvf_check, vfnmacc_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmsac_vf, opfvf_check, vfmsac_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfnmsac_vf, opfvf_check, vfnmsac_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmadd_vf, opfvf_check, vfmadd_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfnmadd_vf, opfvf_check, vfnmadd_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmsub_vf, opfvf_check, vfmsub_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfnmsub_vf, opfvf_check, vfnmsub_vf_h_bf16)
 
 /* Vector Widening Floating-Point Fused Multiply-Add Instructions */
-GEN_OPFVV_WIDEN_TRANS(vfwmacc_vv, opfvv_overwrite_widen_check)
-GEN_OPFVV_WIDEN_TRANS(vfwnmacc_vv, opfvv_overwrite_widen_check)
-GEN_OPFVV_WIDEN_TRANS(vfwmsac_vv, opfvv_overwrite_widen_check)
-GEN_OPFVV_WIDEN_TRANS(vfwnmsac_vv, opfvv_overwrite_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwmacc_vf, opfvf_overwrite_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwnmacc_vf, opfvf_overwrite_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwmsac_vf, opfvf_overwrite_widen_check)
-GEN_OPFVF_WIDEN_TRANS(vfwnmsac_vf, opfvf_overwrite_widen_check)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwmacc_vv, opfvv_overwrite_widen_check,
+                          vfwmaccbf16_vv)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwnmacc_vv, opfvv_overwrite_widen_check,
+                          vfwnmacc_vv_h_bf16)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwmsac_vv, opfvv_overwrite_widen_check,
+                          vfwmsac_vv_h_bf16)
+GEN_OPFVV_WIDEN_BFA_TRANS(vfwnmsac_vv, opfvv_overwrite_widen_check,
+                          vfwnmsac_vv_h_bf16)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwmacc_vf, opfvf_overwrite_widen_check,
+                          vfwmaccbf16_vf)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwnmacc_vf, opfvf_overwrite_widen_check,
+                          vfwnmacc_vf_h_bf16)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwmsac_vf, opfvf_overwrite_widen_check,
+                          vfwmsac_vf_h_bf16)
+GEN_OPFVF_WIDEN_BFA_TRANS(vfwnmsac_vf, opfvf_overwrite_widen_check,
+                          vfwnmsac_vf_h_bf16)
 
 /* Vector Floating-Point Square-Root Instruction */
 
@@ -2660,21 +2788,23 @@ GEN_OPFVF_WIDEN_TRANS(vfwnmsac_vf, opfvf_overwrite_widen_check)
  * If the current SEW does not correspond to a supported IEEE floating-point
  * type, an illegal instruction exception is raised
  */
-static bool opfv_check(DisasContext *s, arg_rmr *a)
+static bool opfv_check(DisasContext *s, arg_rmr *a, int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_rvf(s) &&
            vext_check_isa_ill(s) &&
            /* OPFV instructions ignore vs1 check */
-           vext_check_ss(s, a->rd, a->rs2, a->vm);
+           vext_check_ss(s, a->rd, a->rs2, a->vm) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
 static bool do_opfv(DisasContext *s, arg_rmr *a,
                     gen_helper_gvec_3_ptr *fn,
-                    bool (*checkfn)(DisasContext *, arg_rmr *),
-                    int rm)
+                    bool (*checkfn)(DisasContext *, arg_rmr *, int8_t),
+                    int rm,
+                    int8_t valid_bfa_vsew)
 {
-    if (checkfn(s, a)) {
+    if (checkfn(s, a, valid_bfa_vsew)) {
         uint32_t data = 0;
         gen_set_rm_chkfrm(s, rm);
 
@@ -2692,76 +2822,95 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
     return false;
 }
 
-#define GEN_OPFV_TRANS(NAME, CHECK, FRM)               \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
-{                                                      \
-    static gen_helper_gvec_3_ptr * const fns[3] = {    \
-        gen_helper_##NAME##_h,                         \
-        gen_helper_##NAME##_w,                         \
-        gen_helper_##NAME##_d                          \
-    };                                                 \
-    return do_opfv(s, a, fns[s->sew - 1], CHECK, FRM); \
+#define GEN_OPFV_TRANS(NAME, CHECK, FRM)                    \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)       \
+{                                                           \
+    static gen_helper_gvec_3_ptr * const fns[3] = {         \
+        gen_helper_##NAME##_h,                              \
+        gen_helper_##NAME##_w,                              \
+        gen_helper_##NAME##_d                               \
+    };                                                      \
+    return do_opfv(s, a, fns[s->sew - 1], CHECK, FRM, -1);  \
+}
+
+#define GEN_OPFV_BFA_TRANS(NAME, CHECK, FRM)                    \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)           \
+{                                                               \
+    static gen_helper_gvec_3_ptr * const fns[3] = {             \
+        gen_helper_##NAME##_h,                                  \
+        gen_helper_##NAME##_w,                                  \
+        gen_helper_##NAME##_d                                   \
+    };                                                          \
+    return do_opfv(s, a,                                        \
+                   (s->altfmt ? gen_helper_##NAME##_h_bf16 :    \
+                                fns[s->sew - 1]),               \
+                   CHECK, FRM, MO_16);                          \
 }
 
 GEN_OPFV_TRANS(vfsqrt_v, opfv_check, RISCV_FRM_DYN)
-GEN_OPFV_TRANS(vfrsqrt7_v, opfv_check, RISCV_FRM_DYN)
-GEN_OPFV_TRANS(vfrec7_v, opfv_check, RISCV_FRM_DYN)
+GEN_OPFV_BFA_TRANS(vfrsqrt7_v, opfv_check, RISCV_FRM_DYN)
+GEN_OPFV_BFA_TRANS(vfrec7_v, opfv_check, RISCV_FRM_DYN)
 
 /* Vector Floating-Point MIN/MAX Instructions */
-GEN_OPFVV_TRANS(vfmin_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfmax_vv, opfvv_check)
-GEN_OPFVF_TRANS(vfmin_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfmax_vf, opfvf_check)
+GEN_OPFVV_BFA_TRANS(vfmin_vv, opfvv_check, vfmin_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vfmax_vv, opfvv_check, vfmax_vv_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmin_vf, opfvf_check, vfmin_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vfmax_vf, opfvf_check, vfmax_vf_h_bf16)
 
 /* Vector Floating-Point Sign-Injection Instructions */
-GEN_OPFVV_TRANS(vfsgnj_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfsgnjn_vv, opfvv_check)
-GEN_OPFVV_TRANS(vfsgnjx_vv, opfvv_check)
-GEN_OPFVF_TRANS(vfsgnj_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfsgnjn_vf, opfvf_check)
-GEN_OPFVF_TRANS(vfsgnjx_vf, opfvf_check)
+GEN_OPFVV_BFA_TRANS(vfsgnj_vv, opfvv_check, vfsgnj_vv_h)
+GEN_OPFVV_BFA_TRANS(vfsgnjn_vv, opfvv_check, vfsgnjn_vv_h)
+GEN_OPFVV_BFA_TRANS(vfsgnjx_vv, opfvv_check, vfsgnjx_vv_h)
+GEN_OPFVF_BFA_TRANS(vfsgnj_vf, opfvf_check, vfsgnj_vf_h)
+GEN_OPFVF_BFA_TRANS(vfsgnjn_vf, opfvf_check, vfsgnjn_vf_h)
+GEN_OPFVF_BFA_TRANS(vfsgnjx_vf, opfvf_check, vfsgnjx_vf_h)
 
 /* Vector Floating-Point Compare Instructions */
-static bool opfvv_cmp_check(DisasContext *s, arg_rmrr *a)
+static bool opfvv_cmp_check(DisasContext *s, arg_rmrr *a,
+                            int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_rvf(s) &&
            vext_check_isa_ill(s) &&
-           vext_check_mss(s, a->rd, a->rs1, a->rs2);
+           vext_check_mss(s, a->rd, a->rs1, a->rs2) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-GEN_OPFVV_TRANS(vmfeq_vv, opfvv_cmp_check)
-GEN_OPFVV_TRANS(vmfne_vv, opfvv_cmp_check)
-GEN_OPFVV_TRANS(vmflt_vv, opfvv_cmp_check)
-GEN_OPFVV_TRANS(vmfle_vv, opfvv_cmp_check)
+GEN_OPFVV_BFA_TRANS(vmfeq_vv, opfvv_cmp_check, vmfeq_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vmfne_vv, opfvv_cmp_check, vmfne_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vmflt_vv, opfvv_cmp_check, vmflt_vv_h_bf16)
+GEN_OPFVV_BFA_TRANS(vmfle_vv, opfvv_cmp_check, vmfle_vv_h_bf16)
 
-static bool opfvf_cmp_check(DisasContext *s, arg_rmrr *a)
+static bool opfvf_cmp_check(DisasContext *s, arg_rmrr *a,
+                            int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_rvf(s) &&
            vext_check_isa_ill(s) &&
-           vext_check_ms(s, a->rd, a->rs2);
+           vext_check_ms(s, a->rd, a->rs2) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-GEN_OPFVF_TRANS(vmfeq_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmfne_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmflt_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmfle_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmfgt_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmfge_vf, opfvf_cmp_check)
+GEN_OPFVF_BFA_TRANS(vmfeq_vf, opfvf_cmp_check, vmfeq_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vmfne_vf, opfvf_cmp_check, vmfne_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vmflt_vf, opfvf_cmp_check, vmflt_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vmfle_vf, opfvf_cmp_check, vmfle_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vmfgt_vf, opfvf_cmp_check, vmfgt_vf_h_bf16)
+GEN_OPFVF_BFA_TRANS(vmfge_vf, opfvf_cmp_check, vmfge_vf_h_bf16)
 
 /* Vector Floating-Point Classify Instruction */
-GEN_OPFV_TRANS(vfclass_v, opfv_check, RISCV_FRM_DYN)
+GEN_OPFV_BFA_TRANS(vfclass_v, opfv_check, RISCV_FRM_DYN)
 
 /* Vector Floating-Point Merge Instruction */
-GEN_OPFVF_TRANS(vfmerge_vfm,  opfvf_check)
+GEN_OPFVF_BFA_TRANS(vfmerge_vfm,  opfvf_check, vfmerge_vfm_h)
 
 static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
 {
     if (require_rvv(s) &&
         require_rvf(s) &&
         vext_check_isa_ill(s) &&
-        require_align(a->rd, s->lmul)) {
+        require_align(a->rd, s->lmul) &&
+        vext_check_altfmt(s, MO_16)) {
         gen_set_rm(s, RISCV_FRM_DYN);
 
         TCGv_i64 t1;
@@ -2782,7 +2931,7 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
             static gen_helper_vmv_vx * const fns[3] = {
                 gen_helper_vmv_v_x_h,
                 gen_helper_vmv_v_x_w,
-                gen_helper_vmv_v_x_d,
+                gen_helper_vmv_v_x_d
             };
 
             t1 = tcg_temp_new_i64();
@@ -2803,15 +2952,15 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
 }
 
 /* Single-Width Floating-Point/Integer Type-Convert Instructions */
-#define GEN_OPFV_CVT_TRANS(NAME, HELPER, FRM)               \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a)       \
-{                                                           \
-    static gen_helper_gvec_3_ptr * const fns[3] = {         \
-        gen_helper_##HELPER##_h,                            \
-        gen_helper_##HELPER##_w,                            \
-        gen_helper_##HELPER##_d                             \
-    };                                                      \
-    return do_opfv(s, a, fns[s->sew - 1], opfv_check, FRM); \
+#define GEN_OPFV_CVT_TRANS(NAME, HELPER, FRM)                   \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)           \
+{                                                               \
+    static gen_helper_gvec_3_ptr * const fns[3] = {             \
+        gen_helper_##HELPER##_h,                                \
+        gen_helper_##HELPER##_w,                                \
+        gen_helper_##HELPER##_d                                 \
+    };                                                          \
+    return do_opfv(s, a, fns[s->sew - 1], opfv_check, FRM, -1); \
 }
 
 GEN_OPFV_CVT_TRANS(vfcvt_xu_f_v, vfcvt_xu_f_v, RISCV_FRM_DYN)
@@ -2835,95 +2984,129 @@ static bool opfv_widen_check(DisasContext *s, arg_rmr *a)
            vext_check_ds(s, a->rd, a->rs2, a->vm);
 }
 
-static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
+static bool opxfv_widen_check(DisasContext *s, arg_rmr *a,
+                              int8_t valid_bfa_vsew)
 {
     return opfv_widen_check(s, a) &&
-           require_rvf(s);
+           require_rvf(s) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
+static bool opffv_widen_check(DisasContext *s, arg_rmr *a,
+                              int8_t valid_bfa_vsew)
 {
     return opfv_widen_check(s, a) &&
            require_rvfmin(s) &&
-           require_scale_rvfmin(s);
-}
-
-#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM)             \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
-{                                                                  \
-    if (CHECK(s, a)) {                                             \
-        uint32_t data = 0;                                         \
-        static gen_helper_gvec_3_ptr * const fns[2] = {            \
-            gen_helper_##HELPER##_h,                               \
-            gen_helper_##HELPER##_w,                               \
-        };                                                         \
-        gen_set_rm_chkfrm(s, FRM);                                 \
-                                                                   \
-        data = FIELD_DP32(data, VDATA, VM, a->vm);                 \
-        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);             \
-        data = FIELD_DP32(data, VDATA, VTA, s->vta);               \
-        data = FIELD_DP32(data, VDATA, VMA, s->vma);               \
-        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),     \
-                           vreg_ofs(s, a->rs2), tcg_env,           \
-                           s->cfg_ptr->vlenb,                      \
-                           s->cfg_ptr->vlenb, data,                \
-                           fns[s->sew - 1]);                       \
-        finalize_rvv_inst(s);                                      \
-        return true;                                               \
-    }                                                              \
-    return false;                                                  \
+           require_scale_rvfmin(s) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
+}
+
+#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM)          \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)           \
+{                                                               \
+    if (CHECK(s, a, -1)) {                                      \
+        uint32_t data = 0;                                      \
+        static gen_helper_gvec_3_ptr * const fns[2] = {         \
+            gen_helper_##HELPER##_h,                            \
+            gen_helper_##HELPER##_w,                            \
+        };                                                      \
+        gen_set_rm_chkfrm(s, FRM);                              \
+                                                                \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);              \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);          \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);            \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);            \
+        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),  \
+                           vreg_ofs(s, a->rs2), tcg_env,        \
+                           s->cfg_ptr->vlenb,                   \
+                           s->cfg_ptr->vlenb, data,             \
+                           fns[s->sew - 1]);                    \
+        finalize_rvv_inst(s);                                   \
+        return true;                                            \
+    }                                                           \
+    return false;                                               \
+}
+
+#define GEN_OPFV_WIDEN_BFA_TRANS(NAME, CHECK, HELPER, FRM, BFA_HELPER)  \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)                   \
+{                                                                       \
+    if (CHECK(s, a, MO_16)) {                                           \
+        uint32_t data = 0;                                              \
+        static gen_helper_gvec_3_ptr * const fns[2] = {                 \
+            gen_helper_##HELPER##_h,                                    \
+            gen_helper_##HELPER##_w,                                    \
+        };                                                              \
+        gen_set_rm_chkfrm(s, FRM);                                      \
+                                                                        \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);                      \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                  \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);                    \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);                    \
+        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),          \
+                           vreg_ofs(s, a->rs2), tcg_env,                \
+                           s->cfg_ptr->vlenb,                           \
+                           s->cfg_ptr->vlenb, data,                     \
+                           (s->altfmt ? gen_helper_##BFA_HELPER :       \
+                                        fns[s->sew - 1]));              \
+        finalize_rvv_inst(s);                                           \
+        return true;                                                    \
+    }                                                                   \
+    return false;                                                       \
 }
 
 GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v, opxfv_widen_check, vfwcvt_xu_f_v,
                      RISCV_FRM_DYN)
 GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v, opxfv_widen_check, vfwcvt_x_f_v,
                      RISCV_FRM_DYN)
-GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v, opffv_widen_check, vfwcvt_f_f_v,
-                     RISCV_FRM_DYN)
+GEN_OPFV_WIDEN_BFA_TRANS(vfwcvt_f_f_v, opffv_widen_check, vfwcvt_f_f_v,
+                         RISCV_FRM_DYN, vfwcvtbf16_f_f_v)
 /* Reuse the helper functions from vfwcvt.xu.f.v and vfwcvt.x.f.v */
 GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_xu_f_v, opxfv_widen_check, vfwcvt_xu_f_v,
                      RISCV_FRM_RTZ)
 GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_x_f_v, opxfv_widen_check, vfwcvt_x_f_v,
                      RISCV_FRM_RTZ)
 
-static bool opfxv_widen_check(DisasContext *s, arg_rmr *a)
+static bool opfxv_widen_check(DisasContext *s, arg_rmr *a,
+                              int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_scale_rvf(s) &&
            vext_check_isa_ill(s) &&
            /* OPFV widening instructions ignore vs1 check */
-           vext_check_ds(s, a->rd, a->rs2, a->vm);
+           vext_check_ds(s, a->rd, a->rs2, a->vm) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-#define GEN_OPFXV_WIDEN_TRANS(NAME)                                \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
-{                                                                  \
-    if (opfxv_widen_check(s, a)) {                                 \
-        uint32_t data = 0;                                         \
-        static gen_helper_gvec_3_ptr * const fns[3] = {            \
-            gen_helper_##NAME##_b,                                 \
-            gen_helper_##NAME##_h,                                 \
-            gen_helper_##NAME##_w,                                 \
-        };                                                         \
-        gen_set_rm(s, RISCV_FRM_DYN);                              \
-                                                                   \
-        data = FIELD_DP32(data, VDATA, VM, a->vm);                 \
-        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);             \
-        data = FIELD_DP32(data, VDATA, VTA, s->vta);               \
-        data = FIELD_DP32(data, VDATA, VMA, s->vma);               \
-        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),     \
-                           vreg_ofs(s, a->rs2), tcg_env,           \
-                           s->cfg_ptr->vlenb,                      \
-                           s->cfg_ptr->vlenb, data,                \
-                           fns[s->sew]);                           \
-        finalize_rvv_inst(s);                                      \
-        return true;                                               \
-    }                                                              \
-    return false;                                                  \
+#define GEN_OPFXV_WIDEN_BFA_TRANS(NAME)                                 \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)                   \
+{                                                                       \
+    if (opfxv_widen_check(s, a, MO_8)) {                                \
+        uint32_t data = 0;                                              \
+        static gen_helper_gvec_3_ptr * const fns[3] = {                 \
+            gen_helper_##NAME##_b,                                      \
+            gen_helper_##NAME##_h,                                      \
+            gen_helper_##NAME##_w                                       \
+        };                                                              \
+        gen_set_rm(s, RISCV_FRM_DYN);                                   \
+                                                                        \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);                      \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                  \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);                    \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);                    \
+        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),          \
+                           vreg_ofs(s, a->rs2), tcg_env,                \
+                           s->cfg_ptr->vlenb,                           \
+                           s->cfg_ptr->vlenb, data,                     \
+                           (s->altfmt ? gen_helper_##NAME##_b_bf16 :    \
+                                        fns[s->sew]));                  \
+        finalize_rvv_inst(s);                                           \
+        return true;                                                    \
+    }                                                                   \
+    return false;                                                       \
 }
 
-GEN_OPFXV_WIDEN_TRANS(vfwcvt_f_xu_v)
-GEN_OPFXV_WIDEN_TRANS(vfwcvt_f_x_v)
+GEN_OPFXV_WIDEN_BFA_TRANS(vfwcvt_f_xu_v)
+GEN_OPFXV_WIDEN_BFA_TRANS(vfwcvt_f_x_v)
 
 /* Narrowing Floating-Point/Integer Type-Convert Instructions */
 
@@ -2939,104 +3122,140 @@ static bool opfv_narrow_check(DisasContext *s, arg_rmr *a)
            vext_check_sd(s, a->rd, a->rs2, a->vm);
 }
 
-static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
+static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a,
+                               int8_t valid_bfa_vsew)
 {
     return opfv_narrow_check(s, a) &&
            require_rvf(s) &&
-           (s->sew != MO_64);
+           (s->sew != MO_64) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
+static bool opffv_narrow_check(DisasContext *s, arg_rmr *a,
+                               int8_t valid_bfa_vsew)
 {
     return opfv_narrow_check(s, a) &&
            require_rvfmin(s) &&
-           require_scale_rvfmin(s);
+           require_scale_rvfmin(s) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
+static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a,
+                                   int8_t valid_bfa_vsew)
 {
     return opfv_narrow_check(s, a) &&
            require_rvf(s) &&
-           require_scale_rvf(s);
-}
-
-#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM)            \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
-{                                                                  \
-    if (CHECK(s, a)) {                                             \
-        uint32_t data = 0;                                         \
-        static gen_helper_gvec_3_ptr * const fns[2] = {            \
-            gen_helper_##HELPER##_h,                               \
-            gen_helper_##HELPER##_w,                               \
-        };                                                         \
-        gen_set_rm_chkfrm(s, FRM);                                 \
-                                                                   \
-        data = FIELD_DP32(data, VDATA, VM, a->vm);                 \
-        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);             \
-        data = FIELD_DP32(data, VDATA, VTA, s->vta);               \
-        data = FIELD_DP32(data, VDATA, VMA, s->vma);               \
-        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),     \
-                           vreg_ofs(s, a->rs2), tcg_env,           \
-                           s->cfg_ptr->vlenb,                      \
-                           s->cfg_ptr->vlenb, data,                \
-                           fns[s->sew - 1]);                       \
-        finalize_rvv_inst(s);                                      \
-        return true;                                               \
-    }                                                              \
-    return false;                                                  \
+           require_scale_rvf(s) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
+}
+
+#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM)         \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)           \
+{                                                               \
+    if (CHECK(s, a, -1)) {                                      \
+        uint32_t data = 0;                                      \
+        static gen_helper_gvec_3_ptr * const fns[2] = {         \
+            gen_helper_##HELPER##_h,                            \
+            gen_helper_##HELPER##_w,                            \
+        };                                                      \
+        gen_set_rm_chkfrm(s, FRM);                              \
+                                                                \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);              \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);          \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);            \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);            \
+        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),  \
+                           vreg_ofs(s, a->rs2), tcg_env,        \
+                           s->cfg_ptr->vlenb,                   \
+                           s->cfg_ptr->vlenb, data,             \
+                           fns[s->sew - 1]);                    \
+        finalize_rvv_inst(s);                                   \
+        return true;                                            \
+    }                                                           \
+    return false;                                               \
+}
+
+#define GEN_OPFV_NARROW_BFA_TRANS(NAME, CHECK, HELPER, FRM, BFA_HELPER) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)                   \
+{                                                                       \
+    if (CHECK(s, a, MO_16)) {                                           \
+        uint32_t data = 0;                                              \
+        static gen_helper_gvec_3_ptr * const fns[2] = {                 \
+            gen_helper_##HELPER##_h,                                    \
+            gen_helper_##HELPER##_w,                                    \
+        };                                                              \
+        gen_set_rm_chkfrm(s, FRM);                                      \
+                                                                        \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);                      \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                  \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);                    \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);                    \
+        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),          \
+                           vreg_ofs(s, a->rs2), tcg_env,                \
+                           s->cfg_ptr->vlenb,                           \
+                           s->cfg_ptr->vlenb, data,                     \
+                           (s->altfmt ? gen_helper_##BFA_HELPER :       \
+                                        fns[s->sew - 1]));              \
+        finalize_rvv_inst(s);                                           \
+        return true;                                                    \
+    }                                                                   \
+    return false;                                                       \
 }
 
 GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_w, opfxv_narrow_check, vfncvt_f_xu_w,
                       RISCV_FRM_DYN)
 GEN_OPFV_NARROW_TRANS(vfncvt_f_x_w, opfxv_narrow_check, vfncvt_f_x_w,
                       RISCV_FRM_DYN)
-GEN_OPFV_NARROW_TRANS(vfncvt_f_f_w, opffv_narrow_check, vfncvt_f_f_w,
-                      RISCV_FRM_DYN)
+GEN_OPFV_NARROW_BFA_TRANS(vfncvt_f_f_w, opffv_narrow_check, vfncvt_f_f_w,
+                          RISCV_FRM_DYN, vfncvtbf16_f_f_w)
 /* Reuse the helper function from vfncvt.f.f.w */
-GEN_OPFV_NARROW_TRANS(vfncvt_rod_f_f_w, opffv_rod_narrow_check, vfncvt_f_f_w,
-                      RISCV_FRM_ROD)
+GEN_OPFV_NARROW_BFA_TRANS(vfncvt_rod_f_f_w, opffv_rod_narrow_check,
+                          vfncvt_f_f_w, RISCV_FRM_ROD, vfncvtbf16_f_f_w)
 
-static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
+static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a,
+                               int8_t valid_bfa_vsew)
 {
     return require_rvv(s) &&
            require_scale_rvf(s) &&
            vext_check_isa_ill(s) &&
            /* OPFV narrowing instructions ignore vs1 check */
-           vext_check_sd(s, a->rd, a->rs2, a->vm);
+           vext_check_sd(s, a->rd, a->rs2, a->vm) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-#define GEN_OPXFV_NARROW_TRANS(NAME, HELPER, FRM)                  \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
-{                                                                  \
-    if (opxfv_narrow_check(s, a)) {                                \
-        uint32_t data = 0;                                         \
-        static gen_helper_gvec_3_ptr * const fns[3] = {            \
-            gen_helper_##HELPER##_b,                               \
-            gen_helper_##HELPER##_h,                               \
-            gen_helper_##HELPER##_w,                               \
-        };                                                         \
-        gen_set_rm_chkfrm(s, FRM);                                 \
-                                                                   \
-        data = FIELD_DP32(data, VDATA, VM, a->vm);                 \
-        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);             \
-        data = FIELD_DP32(data, VDATA, VTA, s->vta);               \
-        data = FIELD_DP32(data, VDATA, VMA, s->vma);               \
-        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),     \
-                           vreg_ofs(s, a->rs2), tcg_env,           \
-                           s->cfg_ptr->vlenb,                      \
-                           s->cfg_ptr->vlenb, data,                \
-                           fns[s->sew]);                           \
-        finalize_rvv_inst(s);                                      \
-        return true;                                               \
-    }                                                              \
-    return false;                                                  \
+#define GEN_OPXFV_NARROW_BFA_TRANS(NAME, HELPER, FRM)                   \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)                   \
+{                                                                       \
+    if (opxfv_narrow_check(s, a, MO_8)) {                               \
+        uint32_t data = 0;                                              \
+        static gen_helper_gvec_3_ptr * const fns[3] = {                 \
+            gen_helper_##HELPER##_b,                                    \
+            gen_helper_##HELPER##_h,                                    \
+            gen_helper_##HELPER##_w                                     \
+        };                                                              \
+        gen_set_rm_chkfrm(s, FRM);                                      \
+                                                                        \
+        data = FIELD_DP32(data, VDATA, VM, a->vm);                      \
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);                  \
+        data = FIELD_DP32(data, VDATA, VTA, s->vta);                    \
+        data = FIELD_DP32(data, VDATA, VMA, s->vma);                    \
+        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),          \
+                           vreg_ofs(s, a->rs2), tcg_env,                \
+                           s->cfg_ptr->vlenb,                           \
+                           s->cfg_ptr->vlenb, data,                     \
+                           (s->altfmt ? gen_helper_##HELPER##_b_bf16 :  \
+                                        fns[s->sew]));                  \
+        finalize_rvv_inst(s);                                           \
+        return true;                                                    \
+    }                                                                   \
+    return false;                                                       \
 }
 
-GEN_OPXFV_NARROW_TRANS(vfncvt_xu_f_w, vfncvt_xu_f_w, RISCV_FRM_DYN)
-GEN_OPXFV_NARROW_TRANS(vfncvt_x_f_w, vfncvt_x_f_w, RISCV_FRM_DYN)
+GEN_OPXFV_NARROW_BFA_TRANS(vfncvt_xu_f_w, vfncvt_xu_f_w, RISCV_FRM_DYN)
+GEN_OPXFV_NARROW_BFA_TRANS(vfncvt_x_f_w, vfncvt_x_f_w, RISCV_FRM_DYN)
 /* Reuse the helper functions from vfncvt.xu.f.w and vfncvt.x.f.w */
-GEN_OPXFV_NARROW_TRANS(vfncvt_rtz_xu_f_w, vfncvt_xu_f_w, RISCV_FRM_RTZ)
-GEN_OPXFV_NARROW_TRANS(vfncvt_rtz_x_f_w, vfncvt_x_f_w, RISCV_FRM_RTZ)
+GEN_OPXFV_NARROW_BFA_TRANS(vfncvt_rtz_xu_f_w, vfncvt_xu_f_w, RISCV_FRM_RTZ)
+GEN_OPXFV_NARROW_BFA_TRANS(vfncvt_rtz_x_f_w, vfncvt_x_f_w, RISCV_FRM_RTZ)
 
 /*
  *** Vector Reduction Operations
@@ -3069,10 +3288,12 @@ GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_widen_check)
 
 /* Vector Single-Width Floating-Point Reduction Instructions */
-static bool freduction_check(DisasContext *s, arg_rmrr *a)
+static bool freduction_check(DisasContext *s, arg_rmrr *a,
+                             int8_t valid_bfa_vsew)
 {
     return reduction_check(s, a) &&
-           require_rvf(s);
+           require_rvf(s) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
 GEN_OPFVV_TRANS(vfredusum_vs, freduction_check)
@@ -3081,11 +3302,13 @@ GEN_OPFVV_TRANS(vfredmax_vs, freduction_check)
 GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
 
 /* Vector Widening Floating-Point Reduction Instructions */
-static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
+static bool freduction_widen_check(DisasContext *s, arg_rmrr *a,
+                                   int8_t valid_bfa_vsew)
 {
     return reduction_widen_check(s, a) &&
            require_rvf(s) &&
-           require_scale_rvf(s);
+           require_scale_rvf(s) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
 GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
@@ -3500,7 +3723,8 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
 {
     if (require_rvv(s) &&
         require_rvf(s) &&
-        vext_check_isa_ill(s)) {
+        vext_check_isa_ill(s) &&
+        vext_check_altfmt(s, MO_16)) {
         gen_set_rm(s, RISCV_FRM_DYN);
 
         /* The instructions ignore LMUL and vector register group. */
@@ -3594,20 +3818,24 @@ GEN_OPIVX_VSLIDE1_TRANS(vslide1up_vx, slideup_check)
 GEN_OPIVX_VSLIDE1_TRANS(vslide1down_vx, slidedown_check)
 
 /* Vector Floating-Point Slide Instructions */
-static bool fslideup_check(DisasContext *s, arg_rmrr *a)
+static bool fslideup_check(DisasContext *s, arg_rmrr *a,
+                           int8_t valid_bfa_vsew)
 {
     return slideup_check(s, a) &&
-           require_rvf(s);
+           require_rvf(s) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-static bool fslidedown_check(DisasContext *s, arg_rmrr *a)
+static bool fslidedown_check(DisasContext *s, arg_rmrr *a,
+                             int8_t valid_bfa_vsew)
 {
     return slidedown_check(s, a) &&
-           require_rvf(s);
+           require_rvf(s) &&
+           vext_check_altfmt(s, valid_bfa_vsew);
 }
 
-GEN_OPFVF_TRANS(vfslide1up_vf, fslideup_check)
-GEN_OPFVF_TRANS(vfslide1down_vf, fslidedown_check)
+GEN_OPFVF_BFA_TRANS(vfslide1up_vf, fslideup_check, vfslide1up_vf_h)
+GEN_OPFVF_BFA_TRANS(vfslide1down_vf, fslidedown_check, vfslide1down_vf_h)
 
 /* Vector Register Gather Instruction */
 static bool vrgather_vv_check(DisasContext *s, arg_rmrr *a)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 35b923c4bf..db7d7dce63 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -72,6 +72,7 @@ FIELD(VDATA, NF, 7, 4)
 FIELD(VDATA, WD, 7, 1)
 
 /* float point classify helpers */
+target_ulong fclass_h_bf16(uint64_t frs1);
 target_ulong fclass_h(uint64_t frs1);
 target_ulong fclass_s(uint64_t frs1);
 target_ulong fclass_d(uint64_t frs1);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index b7105627ed..f75177b0fc 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3177,9 +3177,11 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,          \
                       total_elems * ESZ);                 \
 }
 
+RVVCALL(OPFVV2, vfadd_vv_h_bf16, OP_UUU_H, H2, H2, H2, bfloat16_add)
 RVVCALL(OPFVV2, vfadd_vv_h, OP_UUU_H, H2, H2, H2, float16_add)
 RVVCALL(OPFVV2, vfadd_vv_w, OP_UUU_W, H4, H4, H4, float32_add)
 RVVCALL(OPFVV2, vfadd_vv_d, OP_UUU_D, H8, H8, H8, float64_add)
+GEN_VEXT_VV_ENV(vfadd_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfadd_vv_h, 2)
 GEN_VEXT_VV_ENV(vfadd_vv_w, 4)
 GEN_VEXT_VV_ENV(vfadd_vv_d, 8)
@@ -3222,26 +3224,37 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1,        \
                       total_elems * ESZ);                 \
 }
 
+RVVCALL(OPFVF2, vfadd_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_add)
 RVVCALL(OPFVF2, vfadd_vf_h, OP_UUU_H, H2, H2, float16_add)
 RVVCALL(OPFVF2, vfadd_vf_w, OP_UUU_W, H4, H4, float32_add)
 RVVCALL(OPFVF2, vfadd_vf_d, OP_UUU_D, H8, H8, float64_add)
+GEN_VEXT_VF(vfadd_vf_h_bf16, 2)
 GEN_VEXT_VF(vfadd_vf_h, 2)
 GEN_VEXT_VF(vfadd_vf_w, 4)
 GEN_VEXT_VF(vfadd_vf_d, 8)
 
+RVVCALL(OPFVV2, vfsub_vv_h_bf16, OP_UUU_H, H2, H2, H2, bfloat16_sub)
 RVVCALL(OPFVV2, vfsub_vv_h, OP_UUU_H, H2, H2, H2, float16_sub)
 RVVCALL(OPFVV2, vfsub_vv_w, OP_UUU_W, H4, H4, H4, float32_sub)
 RVVCALL(OPFVV2, vfsub_vv_d, OP_UUU_D, H8, H8, H8, float64_sub)
+GEN_VEXT_VV_ENV(vfsub_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfsub_vv_h, 2)
 GEN_VEXT_VV_ENV(vfsub_vv_w, 4)
 GEN_VEXT_VV_ENV(vfsub_vv_d, 8)
+RVVCALL(OPFVF2, vfsub_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_sub)
 RVVCALL(OPFVF2, vfsub_vf_h, OP_UUU_H, H2, H2, float16_sub)
 RVVCALL(OPFVF2, vfsub_vf_w, OP_UUU_W, H4, H4, float32_sub)
 RVVCALL(OPFVF2, vfsub_vf_d, OP_UUU_D, H8, H8, float64_sub)
+GEN_VEXT_VF(vfsub_vf_h_bf16, 2)
 GEN_VEXT_VF(vfsub_vf_h, 2)
 GEN_VEXT_VF(vfsub_vf_w, 4)
 GEN_VEXT_VF(vfsub_vf_d, 8)
 
+static uint16_t bfloat16_rsub(uint16_t a, uint16_t b, float_status * s)
+{
+    return bfloat16_sub(b, a, s);
+}
+
 static uint16_t float16_rsub(uint16_t a, uint16_t b, float_status *s)
 {
     return float16_sub(b, a, s);
@@ -3257,14 +3270,22 @@ static uint64_t float64_rsub(uint64_t a, uint64_t b, float_status *s)
     return float64_sub(b, a, s);
 }
 
+RVVCALL(OPFVF2, vfrsub_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_rsub)
 RVVCALL(OPFVF2, vfrsub_vf_h, OP_UUU_H, H2, H2, float16_rsub)
 RVVCALL(OPFVF2, vfrsub_vf_w, OP_UUU_W, H4, H4, float32_rsub)
 RVVCALL(OPFVF2, vfrsub_vf_d, OP_UUU_D, H8, H8, float64_rsub)
+GEN_VEXT_VF(vfrsub_vf_h_bf16, 2)
 GEN_VEXT_VF(vfrsub_vf_h, 2)
 GEN_VEXT_VF(vfrsub_vf_w, 4)
 GEN_VEXT_VF(vfrsub_vf_d, 8)
 
 /* Vector Widening Floating-Point Add/Subtract Instructions */
+static uint32_t vfwadd16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+    return float32_add(bfloat16_to_float32(a, s),
+                       bfloat16_to_float32(b, s), s);
+}
+
 static uint32_t vfwadd16(uint16_t a, uint16_t b, float_status *s)
 {
     return float32_add(float16_to_float32(a, true, s),
@@ -3278,15 +3299,25 @@ static uint64_t vfwadd32(uint32_t a, uint32_t b, float_status *s)
 
 }
 
+RVVCALL(OPFVV2, vfwadd_vv_h_bf16, WOP_UUU_H, H4, H2, H2, vfwadd16_bf16)
 RVVCALL(OPFVV2, vfwadd_vv_h, WOP_UUU_H, H4, H2, H2, vfwadd16)
 RVVCALL(OPFVV2, vfwadd_vv_w, WOP_UUU_W, H8, H4, H4, vfwadd32)
+GEN_VEXT_VV_ENV(vfwadd_vv_h_bf16, 4)
 GEN_VEXT_VV_ENV(vfwadd_vv_h, 4)
 GEN_VEXT_VV_ENV(vfwadd_vv_w, 8)
+RVVCALL(OPFVF2, vfwadd_vf_h_bf16, WOP_UUU_H, H4, H2, vfwadd16_bf16)
 RVVCALL(OPFVF2, vfwadd_vf_h, WOP_UUU_H, H4, H2, vfwadd16)
 RVVCALL(OPFVF2, vfwadd_vf_w, WOP_UUU_W, H8, H4, vfwadd32)
+GEN_VEXT_VF(vfwadd_vf_h_bf16, 4)
 GEN_VEXT_VF(vfwadd_vf_h, 4)
 GEN_VEXT_VF(vfwadd_vf_w, 8)
 
+static uint32_t vfwsub16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+    return float32_sub(bfloat16_to_float32(a, s),
+                       bfloat16_to_float32(b, s), s);
+}
+
 static uint32_t vfwsub16(uint16_t a, uint16_t b, float_status *s)
 {
     return float32_sub(float16_to_float32(a, true, s),
@@ -3300,15 +3331,24 @@ static uint64_t vfwsub32(uint32_t a, uint32_t b, float_status *s)
 
 }
 
+RVVCALL(OPFVV2, vfwsub_vv_h_bf16, WOP_UUU_H, H4, H2, H2, vfwsub16_bf16)
 RVVCALL(OPFVV2, vfwsub_vv_h, WOP_UUU_H, H4, H2, H2, vfwsub16)
 RVVCALL(OPFVV2, vfwsub_vv_w, WOP_UUU_W, H8, H4, H4, vfwsub32)
+GEN_VEXT_VV_ENV(vfwsub_vv_h_bf16, 4)
 GEN_VEXT_VV_ENV(vfwsub_vv_h, 4)
 GEN_VEXT_VV_ENV(vfwsub_vv_w, 8)
+RVVCALL(OPFVF2, vfwsub_vf_h_bf16, WOP_UUU_H, H4, H2, vfwsub16_bf16)
 RVVCALL(OPFVF2, vfwsub_vf_h, WOP_UUU_H, H4, H2, vfwsub16)
 RVVCALL(OPFVF2, vfwsub_vf_w, WOP_UUU_W, H8, H4, vfwsub32)
+GEN_VEXT_VF(vfwsub_vf_h_bf16, 4)
 GEN_VEXT_VF(vfwsub_vf_h, 4)
 GEN_VEXT_VF(vfwsub_vf_w, 8)
 
+static uint32_t vfwaddw16_bf16(uint32_t a, uint16_t b, float_status *s)
+{
+    return float32_add(a, bfloat16_to_float32(b, s), s);
+}
+
 static uint32_t vfwaddw16(uint32_t a, uint16_t b, float_status *s)
 {
     return float32_add(a, float16_to_float32(b, true, s), s);
@@ -3319,15 +3359,24 @@ static uint64_t vfwaddw32(uint64_t a, uint32_t b, float_status *s)
     return float64_add(a, float32_to_float64(b, s), s);
 }
 
+RVVCALL(OPFVV2, vfwadd_wv_h_bf16, WOP_WUUU_H, H4, H2, H2, vfwaddw16_bf16)
 RVVCALL(OPFVV2, vfwadd_wv_h, WOP_WUUU_H, H4, H2, H2, vfwaddw16)
 RVVCALL(OPFVV2, vfwadd_wv_w, WOP_WUUU_W, H8, H4, H4, vfwaddw32)
+GEN_VEXT_VV_ENV(vfwadd_wv_h_bf16, 4)
 GEN_VEXT_VV_ENV(vfwadd_wv_h, 4)
 GEN_VEXT_VV_ENV(vfwadd_wv_w, 8)
+RVVCALL(OPFVF2, vfwadd_wf_h_bf16, WOP_WUUU_H, H4, H2, vfwaddw16_bf16)
 RVVCALL(OPFVF2, vfwadd_wf_h, WOP_WUUU_H, H4, H2, vfwaddw16)
 RVVCALL(OPFVF2, vfwadd_wf_w, WOP_WUUU_W, H8, H4, vfwaddw32)
+GEN_VEXT_VF(vfwadd_wf_h_bf16, 4)
 GEN_VEXT_VF(vfwadd_wf_h, 4)
 GEN_VEXT_VF(vfwadd_wf_w, 8)
 
+static uint32_t vfwsubw16_bf16(uint32_t a, uint16_t b, float_status *s)
+{
+    return float32_sub(a, bfloat16_to_float32(b, s), s);
+}
+
 static uint32_t vfwsubw16(uint32_t a, uint16_t b, float_status *s)
 {
     return float32_sub(a, float16_to_float32(b, true, s), s);
@@ -3338,25 +3387,33 @@ static uint64_t vfwsubw32(uint64_t a, uint32_t b, float_status *s)
     return float64_sub(a, float32_to_float64(b, s), s);
 }
 
+RVVCALL(OPFVV2, vfwsub_wv_h_bf16, WOP_WUUU_H, H4, H2, H2, vfwsubw16_bf16)
 RVVCALL(OPFVV2, vfwsub_wv_h, WOP_WUUU_H, H4, H2, H2, vfwsubw16)
 RVVCALL(OPFVV2, vfwsub_wv_w, WOP_WUUU_W, H8, H4, H4, vfwsubw32)
+GEN_VEXT_VV_ENV(vfwsub_wv_h_bf16, 4)
 GEN_VEXT_VV_ENV(vfwsub_wv_h, 4)
 GEN_VEXT_VV_ENV(vfwsub_wv_w, 8)
+RVVCALL(OPFVF2, vfwsub_wf_h_bf16, WOP_WUUU_H, H4, H2, vfwsubw16_bf16)
 RVVCALL(OPFVF2, vfwsub_wf_h, WOP_WUUU_H, H4, H2, vfwsubw16)
 RVVCALL(OPFVF2, vfwsub_wf_w, WOP_WUUU_W, H8, H4, vfwsubw32)
+GEN_VEXT_VF(vfwsub_wf_h_bf16, 4)
 GEN_VEXT_VF(vfwsub_wf_h, 4)
 GEN_VEXT_VF(vfwsub_wf_w, 8)
 
 /* Vector Single-Width Floating-Point Multiply/Divide Instructions */
+RVVCALL(OPFVV2, vfmul_vv_h_bf16, OP_UUU_H, H2, H2, H2, bfloat16_mul)
 RVVCALL(OPFVV2, vfmul_vv_h, OP_UUU_H, H2, H2, H2, float16_mul)
 RVVCALL(OPFVV2, vfmul_vv_w, OP_UUU_W, H4, H4, H4, float32_mul)
 RVVCALL(OPFVV2, vfmul_vv_d, OP_UUU_D, H8, H8, H8, float64_mul)
+GEN_VEXT_VV_ENV(vfmul_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfmul_vv_h, 2)
 GEN_VEXT_VV_ENV(vfmul_vv_w, 4)
 GEN_VEXT_VV_ENV(vfmul_vv_d, 8)
+RVVCALL(OPFVF2, vfmul_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_mul)
 RVVCALL(OPFVF2, vfmul_vf_h, OP_UUU_H, H2, H2, float16_mul)
 RVVCALL(OPFVF2, vfmul_vf_w, OP_UUU_W, H4, H4, float32_mul)
 RVVCALL(OPFVF2, vfmul_vf_d, OP_UUU_D, H8, H8, float64_mul)
+GEN_VEXT_VF(vfmul_vf_h_bf16, 2)
 GEN_VEXT_VF(vfmul_vf_h, 2)
 GEN_VEXT_VF(vfmul_vf_w, 4)
 GEN_VEXT_VF(vfmul_vf_d, 8)
@@ -3397,6 +3454,12 @@ GEN_VEXT_VF(vfrdiv_vf_w, 4)
 GEN_VEXT_VF(vfrdiv_vf_d, 8)
 
 /* Vector Widening Floating-Point Multiply */
+static uint32_t vfwmul16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+    return float32_mul(bfloat16_to_float32(a, s),
+                       bfloat16_to_float32(b, s), s);
+}
+
 static uint32_t vfwmul16(uint16_t a, uint16_t b, float_status *s)
 {
     return float32_mul(float16_to_float32(a, true, s),
@@ -3409,12 +3472,17 @@ static uint64_t vfwmul32(uint32_t a, uint32_t b, float_status *s)
                        float32_to_float64(b, s), s);
 
 }
+
+RVVCALL(OPFVV2, vfwmul_vv_h_bf16, WOP_UUU_H, H4, H2, H2, vfwmul16_bf16)
 RVVCALL(OPFVV2, vfwmul_vv_h, WOP_UUU_H, H4, H2, H2, vfwmul16)
 RVVCALL(OPFVV2, vfwmul_vv_w, WOP_UUU_W, H8, H4, H4, vfwmul32)
+GEN_VEXT_VV_ENV(vfwmul_vv_h_bf16, 4)
 GEN_VEXT_VV_ENV(vfwmul_vv_h, 4)
 GEN_VEXT_VV_ENV(vfwmul_vv_w, 8)
+RVVCALL(OPFVF2, vfwmul_vf_h_bf16, WOP_UUU_H, H4, H2, vfwmul16_bf16)
 RVVCALL(OPFVF2, vfwmul_vf_h, WOP_UUU_H, H4, H2, vfwmul16)
 RVVCALL(OPFVF2, vfwmul_vf_w, WOP_UUU_W, H8, H4, vfwmul32)
+GEN_VEXT_VF(vfwmul_vf_h_bf16, 4)
 GEN_VEXT_VF(vfwmul_vf_h, 4)
 GEN_VEXT_VF(vfwmul_vf_w, 8)
 
@@ -3429,6 +3497,12 @@ static void do_##NAME(void *vd, void *vs1, void *vs2, int i,       \
     *((TD *)vd + HD(i)) = OP(s2, s1, d, &env->fp_status);          \
 }
 
+static uint16_t fmacc16_bf16(uint16_t a, uint16_t b, uint16_t d,
+                             float_status *s)
+{
+    return bfloat16_muladd(a, b, d, 0, s);
+}
+
 static uint16_t fmacc16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
 {
     return float16_muladd(a, b, d, 0, s);
@@ -3444,9 +3518,11 @@ static uint64_t fmacc64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
     return float64_muladd(a, b, d, 0, s);
 }
 
+RVVCALL(OPFVV3, vfmacc_vv_h_bf16, OP_UUU_H, H2, H2, H2, fmacc16_bf16)
 RVVCALL(OPFVV3, vfmacc_vv_h, OP_UUU_H, H2, H2, H2, fmacc16)
 RVVCALL(OPFVV3, vfmacc_vv_w, OP_UUU_W, H4, H4, H4, fmacc32)
 RVVCALL(OPFVV3, vfmacc_vv_d, OP_UUU_D, H8, H8, H8, fmacc64)
+GEN_VEXT_VV_ENV(vfmacc_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfmacc_vv_h, 2)
 GEN_VEXT_VV_ENV(vfmacc_vv_w, 4)
 GEN_VEXT_VV_ENV(vfmacc_vv_d, 8)
@@ -3460,13 +3536,22 @@ static void do_##NAME(void *vd, uint64_t s1, void *vs2, int i,    \
     *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1, d, &env->fp_status);\
 }
 
+RVVCALL(OPFVF3, vfmacc_vf_h_bf16, OP_UUU_H, H2, H2, fmacc16_bf16)
 RVVCALL(OPFVF3, vfmacc_vf_h, OP_UUU_H, H2, H2, fmacc16)
 RVVCALL(OPFVF3, vfmacc_vf_w, OP_UUU_W, H4, H4, fmacc32)
 RVVCALL(OPFVF3, vfmacc_vf_d, OP_UUU_D, H8, H8, fmacc64)
+GEN_VEXT_VF(vfmacc_vf_h_bf16, 2)
 GEN_VEXT_VF(vfmacc_vf_h, 2)
 GEN_VEXT_VF(vfmacc_vf_w, 4)
 GEN_VEXT_VF(vfmacc_vf_d, 8)
 
+static uint16_t fnmacc16_bf16(uint16_t a, uint16_t b, uint16_t d,
+                              float_status *s)
+{
+    return bfloat16_muladd(a, b, d, float_muladd_negate_c |
+                                    float_muladd_negate_product, s);
+}
+
 static uint16_t fnmacc16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
 {
     return float16_muladd(a, b, d, float_muladd_negate_c |
@@ -3485,19 +3570,29 @@ static uint64_t fnmacc64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
                                    float_muladd_negate_product, s);
 }
 
+RVVCALL(OPFVV3, vfnmacc_vv_h_bf16, OP_UUU_H, H2, H2, H2, fnmacc16_bf16)
 RVVCALL(OPFVV3, vfnmacc_vv_h, OP_UUU_H, H2, H2, H2, fnmacc16)
 RVVCALL(OPFVV3, vfnmacc_vv_w, OP_UUU_W, H4, H4, H4, fnmacc32)
 RVVCALL(OPFVV3, vfnmacc_vv_d, OP_UUU_D, H8, H8, H8, fnmacc64)
+GEN_VEXT_VV_ENV(vfnmacc_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfnmacc_vv_h, 2)
 GEN_VEXT_VV_ENV(vfnmacc_vv_w, 4)
 GEN_VEXT_VV_ENV(vfnmacc_vv_d, 8)
+RVVCALL(OPFVF3, vfnmacc_vf_h_bf16, OP_UUU_H, H2, H2, fnmacc16_bf16)
 RVVCALL(OPFVF3, vfnmacc_vf_h, OP_UUU_H, H2, H2, fnmacc16)
 RVVCALL(OPFVF3, vfnmacc_vf_w, OP_UUU_W, H4, H4, fnmacc32)
 RVVCALL(OPFVF3, vfnmacc_vf_d, OP_UUU_D, H8, H8, fnmacc64)
+GEN_VEXT_VF(vfnmacc_vf_h_bf16, 2)
 GEN_VEXT_VF(vfnmacc_vf_h, 2)
 GEN_VEXT_VF(vfnmacc_vf_w, 4)
 GEN_VEXT_VF(vfnmacc_vf_d, 8)
 
+static uint16_t fmsac16_bf16(uint16_t a, uint16_t b, uint16_t d,
+                             float_status *s)
+{
+    return bfloat16_muladd(a, b, d, float_muladd_negate_c, s);
+}
+
 static uint16_t fmsac16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
 {
     return float16_muladd(a, b, d, float_muladd_negate_c, s);
@@ -3513,19 +3608,29 @@ static uint64_t fmsac64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
     return float64_muladd(a, b, d, float_muladd_negate_c, s);
 }
 
+RVVCALL(OPFVV3, vfmsac_vv_h_bf16, OP_UUU_H, H2, H2, H2, fmsac16_bf16)
 RVVCALL(OPFVV3, vfmsac_vv_h, OP_UUU_H, H2, H2, H2, fmsac16)
 RVVCALL(OPFVV3, vfmsac_vv_w, OP_UUU_W, H4, H4, H4, fmsac32)
 RVVCALL(OPFVV3, vfmsac_vv_d, OP_UUU_D, H8, H8, H8, fmsac64)
+GEN_VEXT_VV_ENV(vfmsac_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfmsac_vv_h, 2)
 GEN_VEXT_VV_ENV(vfmsac_vv_w, 4)
 GEN_VEXT_VV_ENV(vfmsac_vv_d, 8)
+RVVCALL(OPFVF3, vfmsac_vf_h_bf16, OP_UUU_H, H2, H2, fmsac16_bf16)
 RVVCALL(OPFVF3, vfmsac_vf_h, OP_UUU_H, H2, H2, fmsac16)
 RVVCALL(OPFVF3, vfmsac_vf_w, OP_UUU_W, H4, H4, fmsac32)
 RVVCALL(OPFVF3, vfmsac_vf_d, OP_UUU_D, H8, H8, fmsac64)
+GEN_VEXT_VF(vfmsac_vf_h_bf16, 2)
 GEN_VEXT_VF(vfmsac_vf_h, 2)
 GEN_VEXT_VF(vfmsac_vf_w, 4)
 GEN_VEXT_VF(vfmsac_vf_d, 8)
 
+static uint16_t fnmsac16_bf16(uint16_t a, uint16_t b, uint16_t d,
+                              float_status *s)
+{
+    return bfloat16_muladd(a, b, d, float_muladd_negate_product, s);
+}
+
 static uint16_t fnmsac16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
 {
     return float16_muladd(a, b, d, float_muladd_negate_product, s);
@@ -3541,19 +3646,29 @@ static uint64_t fnmsac64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
     return float64_muladd(a, b, d, float_muladd_negate_product, s);
 }
 
+RVVCALL(OPFVV3, vfnmsac_vv_h_bf16, OP_UUU_H, H2, H2, H2, fnmsac16_bf16)
 RVVCALL(OPFVV3, vfnmsac_vv_h, OP_UUU_H, H2, H2, H2, fnmsac16)
 RVVCALL(OPFVV3, vfnmsac_vv_w, OP_UUU_W, H4, H4, H4, fnmsac32)
 RVVCALL(OPFVV3, vfnmsac_vv_d, OP_UUU_D, H8, H8, H8, fnmsac64)
+GEN_VEXT_VV_ENV(vfnmsac_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfnmsac_vv_h, 2)
 GEN_VEXT_VV_ENV(vfnmsac_vv_w, 4)
 GEN_VEXT_VV_ENV(vfnmsac_vv_d, 8)
+RVVCALL(OPFVF3, vfnmsac_vf_h_bf16, OP_UUU_H, H2, H2, fnmsac16_bf16)
 RVVCALL(OPFVF3, vfnmsac_vf_h, OP_UUU_H, H2, H2, fnmsac16)
 RVVCALL(OPFVF3, vfnmsac_vf_w, OP_UUU_W, H4, H4, fnmsac32)
 RVVCALL(OPFVF3, vfnmsac_vf_d, OP_UUU_D, H8, H8, fnmsac64)
+GEN_VEXT_VF(vfnmsac_vf_h_bf16, 2)
 GEN_VEXT_VF(vfnmsac_vf_h, 2)
 GEN_VEXT_VF(vfnmsac_vf_w, 4)
 GEN_VEXT_VF(vfnmsac_vf_d, 8)
 
+static uint16_t fmadd16_bf16(uint16_t a, uint16_t b, uint16_t d,
+                             float_status *s)
+{
+    return bfloat16_muladd(d, b, a, 0, s);
+}
+
 static uint16_t fmadd16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
 {
     return float16_muladd(d, b, a, 0, s);
@@ -3569,19 +3684,30 @@ static uint64_t fmadd64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
     return float64_muladd(d, b, a, 0, s);
 }
 
+RVVCALL(OPFVV3, vfmadd_vv_h_bf16, OP_UUU_H, H2, H2, H2, fmadd16_bf16)
 RVVCALL(OPFVV3, vfmadd_vv_h, OP_UUU_H, H2, H2, H2, fmadd16)
 RVVCALL(OPFVV3, vfmadd_vv_w, OP_UUU_W, H4, H4, H4, fmadd32)
 RVVCALL(OPFVV3, vfmadd_vv_d, OP_UUU_D, H8, H8, H8, fmadd64)
+GEN_VEXT_VV_ENV(vfmadd_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfmadd_vv_h, 2)
 GEN_VEXT_VV_ENV(vfmadd_vv_w, 4)
 GEN_VEXT_VV_ENV(vfmadd_vv_d, 8)
+RVVCALL(OPFVF3, vfmadd_vf_h_bf16, OP_UUU_H, H2, H2, fmadd16_bf16)
 RVVCALL(OPFVF3, vfmadd_vf_h, OP_UUU_H, H2, H2, fmadd16)
 RVVCALL(OPFVF3, vfmadd_vf_w, OP_UUU_W, H4, H4, fmadd32)
 RVVCALL(OPFVF3, vfmadd_vf_d, OP_UUU_D, H8, H8, fmadd64)
+GEN_VEXT_VF(vfmadd_vf_h_bf16, 2)
 GEN_VEXT_VF(vfmadd_vf_h, 2)
 GEN_VEXT_VF(vfmadd_vf_w, 4)
 GEN_VEXT_VF(vfmadd_vf_d, 8)
 
+static uint16_t fnmadd16_bf16(uint16_t a, uint16_t b, uint16_t d,
+                              float_status *s)
+{
+    return bfloat16_muladd(d, b, a, float_muladd_negate_c |
+                                    float_muladd_negate_product, s);
+}
+
 static uint16_t fnmadd16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
 {
     return float16_muladd(d, b, a, float_muladd_negate_c |
@@ -3600,19 +3726,29 @@ static uint64_t fnmadd64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
                                    float_muladd_negate_product, s);
 }
 
+RVVCALL(OPFVV3, vfnmadd_vv_h_bf16, OP_UUU_H, H2, H2, H2, fnmadd16_bf16)
 RVVCALL(OPFVV3, vfnmadd_vv_h, OP_UUU_H, H2, H2, H2, fnmadd16)
 RVVCALL(OPFVV3, vfnmadd_vv_w, OP_UUU_W, H4, H4, H4, fnmadd32)
 RVVCALL(OPFVV3, vfnmadd_vv_d, OP_UUU_D, H8, H8, H8, fnmadd64)
+GEN_VEXT_VV_ENV(vfnmadd_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfnmadd_vv_h, 2)
 GEN_VEXT_VV_ENV(vfnmadd_vv_w, 4)
 GEN_VEXT_VV_ENV(vfnmadd_vv_d, 8)
+RVVCALL(OPFVF3, vfnmadd_vf_h_bf16, OP_UUU_H, H2, H2, fnmadd16_bf16)
 RVVCALL(OPFVF3, vfnmadd_vf_h, OP_UUU_H, H2, H2, fnmadd16)
 RVVCALL(OPFVF3, vfnmadd_vf_w, OP_UUU_W, H4, H4, fnmadd32)
 RVVCALL(OPFVF3, vfnmadd_vf_d, OP_UUU_D, H8, H8, fnmadd64)
+GEN_VEXT_VF(vfnmadd_vf_h_bf16, 2)
 GEN_VEXT_VF(vfnmadd_vf_h, 2)
 GEN_VEXT_VF(vfnmadd_vf_w, 4)
 GEN_VEXT_VF(vfnmadd_vf_d, 8)
 
+static uint16_t fmsub16_bf16(uint16_t a, uint16_t b, uint16_t d,
+                             float_status *s)
+{
+    return bfloat16_muladd(d, b, a, float_muladd_negate_c, s);
+}
+
 static uint16_t fmsub16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
 {
     return float16_muladd(d, b, a, float_muladd_negate_c, s);
@@ -3628,19 +3764,29 @@ static uint64_t fmsub64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
     return float64_muladd(d, b, a, float_muladd_negate_c, s);
 }
 
+RVVCALL(OPFVV3, vfmsub_vv_h_bf16, OP_UUU_H, H2, H2, H2, fmsub16_bf16)
 RVVCALL(OPFVV3, vfmsub_vv_h, OP_UUU_H, H2, H2, H2, fmsub16)
 RVVCALL(OPFVV3, vfmsub_vv_w, OP_UUU_W, H4, H4, H4, fmsub32)
 RVVCALL(OPFVV3, vfmsub_vv_d, OP_UUU_D, H8, H8, H8, fmsub64)
+GEN_VEXT_VV_ENV(vfmsub_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfmsub_vv_h, 2)
 GEN_VEXT_VV_ENV(vfmsub_vv_w, 4)
 GEN_VEXT_VV_ENV(vfmsub_vv_d, 8)
+RVVCALL(OPFVF3, vfmsub_vf_h_bf16, OP_UUU_H, H2, H2, fmsub16_bf16)
 RVVCALL(OPFVF3, vfmsub_vf_h, OP_UUU_H, H2, H2, fmsub16)
 RVVCALL(OPFVF3, vfmsub_vf_w, OP_UUU_W, H4, H4, fmsub32)
 RVVCALL(OPFVF3, vfmsub_vf_d, OP_UUU_D, H8, H8, fmsub64)
+GEN_VEXT_VF(vfmsub_vf_h_bf16, 2)
 GEN_VEXT_VF(vfmsub_vf_h, 2)
 GEN_VEXT_VF(vfmsub_vf_w, 4)
 GEN_VEXT_VF(vfmsub_vf_d, 8)
 
+static uint16_t fnmsub16_bf16(uint16_t a, uint16_t b, uint16_t d,
+                              float_status *s)
+{
+    return bfloat16_muladd(d, b, a, float_muladd_negate_product, s);
+}
+
 static uint16_t fnmsub16(uint16_t a, uint16_t b, uint16_t d, float_status *s)
 {
     return float16_muladd(d, b, a, float_muladd_negate_product, s);
@@ -3656,15 +3802,19 @@ static uint64_t fnmsub64(uint64_t a, uint64_t b, uint64_t d, float_status *s)
     return float64_muladd(d, b, a, float_muladd_negate_product, s);
 }
 
+RVVCALL(OPFVV3, vfnmsub_vv_h_bf16, OP_UUU_H, H2, H2, H2, fnmsub16_bf16)
 RVVCALL(OPFVV3, vfnmsub_vv_h, OP_UUU_H, H2, H2, H2, fnmsub16)
 RVVCALL(OPFVV3, vfnmsub_vv_w, OP_UUU_W, H4, H4, H4, fnmsub32)
 RVVCALL(OPFVV3, vfnmsub_vv_d, OP_UUU_D, H8, H8, H8, fnmsub64)
+GEN_VEXT_VV_ENV(vfnmsub_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfnmsub_vv_h, 2)
 GEN_VEXT_VV_ENV(vfnmsub_vv_w, 4)
 GEN_VEXT_VV_ENV(vfnmsub_vv_d, 8)
+RVVCALL(OPFVF3, vfnmsub_vf_h_bf16, OP_UUU_H, H2, H2, fnmsub16_bf16)
 RVVCALL(OPFVF3, vfnmsub_vf_h, OP_UUU_H, H2, H2, fnmsub16)
 RVVCALL(OPFVF3, vfnmsub_vf_w, OP_UUU_W, H4, H4, fnmsub32)
 RVVCALL(OPFVF3, vfnmsub_vf_d, OP_UUU_D, H8, H8, fnmsub64)
+GEN_VEXT_VF(vfnmsub_vf_h_bf16, 2)
 GEN_VEXT_VF(vfnmsub_vf_h, 2)
 GEN_VEXT_VF(vfnmsub_vf_w, 4)
 GEN_VEXT_VF(vfnmsub_vf_d, 8)
@@ -3702,6 +3852,15 @@ GEN_VEXT_VV_ENV(vfwmaccbf16_vv, 4)
 RVVCALL(OPFVF3, vfwmaccbf16_vf, WOP_UUU_H, H4, H2, fwmaccbf16)
 GEN_VEXT_VF(vfwmaccbf16_vf, 4)
 
+static uint32_t fwnmacc16_bf16(uint16_t a, uint16_t b, uint32_t d,
+                               float_status *s)
+{
+    return float32_muladd(bfloat16_to_float32(a, s),
+                          bfloat16_to_float32(b, s), d,
+                          float_muladd_negate_c | float_muladd_negate_product,
+                          s);
+}
+
 static uint32_t fwnmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
 {
     return float32_muladd(float16_to_float32(a, true, s),
@@ -3717,15 +3876,27 @@ static uint64_t fwnmacc32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
                              float_muladd_negate_product, s);
 }
 
+RVVCALL(OPFVV3, vfwnmacc_vv_h_bf16, WOP_UUU_H, H4, H2, H2, fwnmacc16_bf16)
 RVVCALL(OPFVV3, vfwnmacc_vv_h, WOP_UUU_H, H4, H2, H2, fwnmacc16)
 RVVCALL(OPFVV3, vfwnmacc_vv_w, WOP_UUU_W, H8, H4, H4, fwnmacc32)
+GEN_VEXT_VV_ENV(vfwnmacc_vv_h_bf16, 4)
 GEN_VEXT_VV_ENV(vfwnmacc_vv_h, 4)
 GEN_VEXT_VV_ENV(vfwnmacc_vv_w, 8)
+RVVCALL(OPFVF3, vfwnmacc_vf_h_bf16, WOP_UUU_H, H4, H2, fwnmacc16_bf16)
 RVVCALL(OPFVF3, vfwnmacc_vf_h, WOP_UUU_H, H4, H2, fwnmacc16)
 RVVCALL(OPFVF3, vfwnmacc_vf_w, WOP_UUU_W, H8, H4, fwnmacc32)
+GEN_VEXT_VF(vfwnmacc_vf_h_bf16, 4)
 GEN_VEXT_VF(vfwnmacc_vf_h, 4)
 GEN_VEXT_VF(vfwnmacc_vf_w, 8)
 
+static uint32_t fwmsac16_bf16(uint16_t a, uint16_t b, uint32_t d,
+                              float_status *s)
+{
+    return float32_muladd(bfloat16_to_float32(a, s),
+                          bfloat16_to_float32(b, s), d,
+                          float_muladd_negate_c, s);
+}
+
 static uint32_t fwmsac16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
 {
     return float32_muladd(float16_to_float32(a, true, s),
@@ -3740,15 +3911,27 @@ static uint64_t fwmsac32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
                           float_muladd_negate_c, s);
 }
 
+RVVCALL(OPFVV3, vfwmsac_vv_h_bf16, WOP_UUU_H, H4, H2, H2, fwmsac16_bf16)
 RVVCALL(OPFVV3, vfwmsac_vv_h, WOP_UUU_H, H4, H2, H2, fwmsac16)
 RVVCALL(OPFVV3, vfwmsac_vv_w, WOP_UUU_W, H8, H4, H4, fwmsac32)
+GEN_VEXT_VV_ENV(vfwmsac_vv_h_bf16, 4)
 GEN_VEXT_VV_ENV(vfwmsac_vv_h, 4)
 GEN_VEXT_VV_ENV(vfwmsac_vv_w, 8)
+RVVCALL(OPFVF3, vfwmsac_vf_h_bf16, WOP_UUU_H, H4, H2, fwmsac16_bf16)
 RVVCALL(OPFVF3, vfwmsac_vf_h, WOP_UUU_H, H4, H2, fwmsac16)
 RVVCALL(OPFVF3, vfwmsac_vf_w, WOP_UUU_W, H8, H4, fwmsac32)
+GEN_VEXT_VF(vfwmsac_vf_h_bf16, 4)
 GEN_VEXT_VF(vfwmsac_vf_h, 4)
 GEN_VEXT_VF(vfwmsac_vf_w, 8)
 
+static uint32_t fwnmsac16_bf16(uint16_t a, uint16_t b, uint32_t d,
+                               float_status *s)
+{
+    return float32_muladd(bfloat16_to_float32(a, s),
+                          bfloat16_to_float32(b, s), d,
+                          float_muladd_negate_product, s);
+}
+
 static uint32_t fwnmsac16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
 {
     return float32_muladd(float16_to_float32(a, true, s),
@@ -3763,12 +3946,16 @@ static uint64_t fwnmsac32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
                           float_muladd_negate_product, s);
 }
 
+RVVCALL(OPFVV3, vfwnmsac_vv_h_bf16, WOP_UUU_H, H4, H2, H2, fwnmsac16_bf16)
 RVVCALL(OPFVV3, vfwnmsac_vv_h, WOP_UUU_H, H4, H2, H2, fwnmsac16)
 RVVCALL(OPFVV3, vfwnmsac_vv_w, WOP_UUU_W, H8, H4, H4, fwnmsac32)
+GEN_VEXT_VV_ENV(vfwnmsac_vv_h_bf16, 4)
 GEN_VEXT_VV_ENV(vfwnmsac_vv_h, 4)
 GEN_VEXT_VV_ENV(vfwnmsac_vv_w, 8)
+RVVCALL(OPFVF3, vfwnmsac_vf_h_bf16, WOP_UUU_H, H4, H2, fwnmsac16_bf16)
 RVVCALL(OPFVF3, vfwnmsac_vf_h, WOP_UUU_H, H4, H2, fwnmsac16)
 RVVCALL(OPFVF3, vfwnmsac_vf_w, WOP_UUU_W, H8, H4, fwnmsac32)
+GEN_VEXT_VF(vfwnmsac_vf_h_bf16, 4)
 GEN_VEXT_VF(vfwnmsac_vf_h, 4)
 GEN_VEXT_VF(vfwnmsac_vf_w, 8)
 
@@ -3874,6 +4061,46 @@ static uint64_t frsqrt7(uint64_t f, int exp_size, int frac_size)
     return val;
 }
 
+static bfloat16 frsqrt7_h_bf16(bfloat16 f, float_status *s)
+{
+    int exp_size = 8, frac_size = 7;
+    bool sign = bfloat16_is_neg(f);
+
+    /*
+     * frsqrt7(sNaN) = canonical NaN
+     * frsqrt7(-inf) = canonical NaN
+     * frsqrt7(-normal) = canonical NaN
+     * frsqrt7(-subnormal) = canonical NaN
+     */
+    if (bfloat16_is_signaling_nan(f, s) ||
+        (bfloat16_is_infinity(f) && sign) ||
+        (bfloat16_is_normal(f) && sign) ||
+        (bfloat16_is_zero_or_denormal(f) && !bfloat16_is_zero(f) && sign)) {
+        s->float_exception_flags |= float_flag_invalid;
+        return bfloat16_default_nan(s);
+    }
+
+    /* frsqrt7(qNaN) = canonical NaN */
+    if (bfloat16_is_quiet_nan(f, s)) {
+        return bfloat16_default_nan(s);
+    }
+
+    /* frsqrt7(+-0) = +-inf */
+    if (bfloat16_is_zero(f)) {
+        s->float_exception_flags |= float_flag_divbyzero;
+        return bfloat16_set_sign(bfloat16_infinity, sign);
+    }
+
+    /* frsqrt7(+inf) = +0 */
+    if (bfloat16_is_infinity(f) && !sign) {
+        return bfloat16_set_sign(bfloat16_zero, sign);
+    }
+
+    /* +normal, +subnormal */
+    uint64_t val = frsqrt7(f, exp_size, frac_size);
+    return make_float16(val);
+}
+
 static float16 frsqrt7_h(float16 f, float_status *s)
 {
     int exp_size = 5, frac_size = 10;
@@ -3994,9 +4221,11 @@ static float64 frsqrt7_d(float64 f, float_status *s)
     return make_float64(val);
 }
 
+RVVCALL(OPFVV1, vfrsqrt7_v_h_bf16, OP_UU_H, H2, H2, frsqrt7_h_bf16)
 RVVCALL(OPFVV1, vfrsqrt7_v_h, OP_UU_H, H2, H2, frsqrt7_h)
 RVVCALL(OPFVV1, vfrsqrt7_v_w, OP_UU_W, H4, H4, frsqrt7_s)
 RVVCALL(OPFVV1, vfrsqrt7_v_d, OP_UU_D, H8, H8, frsqrt7_d)
+GEN_VEXT_V_ENV(vfrsqrt7_v_h_bf16, 2)
 GEN_VEXT_V_ENV(vfrsqrt7_v_h, 2)
 GEN_VEXT_V_ENV(vfrsqrt7_v_w, 4)
 GEN_VEXT_V_ENV(vfrsqrt7_v_d, 8)
@@ -4089,6 +4318,38 @@ static uint64_t frec7(uint64_t f, int exp_size, int frac_size,
     return val;
 }
 
+static bfloat16 frec7_h_bf16(bfloat16 f, float_status *s)
+{
+    int exp_size = 8, frac_size = 7;
+    bool sign = bfloat16_is_neg(f);
+
+    /* frec7(+-inf) = +-0 */
+    if (bfloat16_is_infinity(f)) {
+        return bfloat16_set_sign(bfloat16_zero, sign);
+    }
+
+    /* frec7(+-0) = +-inf */
+    if (bfloat16_is_zero(f)) {
+        s->float_exception_flags |= float_flag_divbyzero;
+        return bfloat16_set_sign(bfloat16_infinity, sign);
+    }
+
+    /* frec7(sNaN) = canonical NaN */
+    if (bfloat16_is_signaling_nan(f, s)) {
+        s->float_exception_flags |= float_flag_invalid;
+        return bfloat16_default_nan(s);
+    }
+
+    /* frec7(qNaN) = canonical NaN */
+    if (bfloat16_is_quiet_nan(f, s)) {
+        return bfloat16_default_nan(s);
+    }
+
+    /* +-normal, +-subnormal */
+    uint64_t val = frec7(f, exp_size, frac_size, s);
+    return make_float16(val);
+}
+
 static float16 frec7_h(float16 f, float_status *s)
 {
     int exp_size = 5, frac_size = 10;
@@ -4185,36 +4446,46 @@ static float64 frec7_d(float64 f, float_status *s)
     return make_float64(val);
 }
 
+RVVCALL(OPFVV1, vfrec7_v_h_bf16, OP_UU_H, H2, H2, frec7_h_bf16)
 RVVCALL(OPFVV1, vfrec7_v_h, OP_UU_H, H2, H2, frec7_h)
 RVVCALL(OPFVV1, vfrec7_v_w, OP_UU_W, H4, H4, frec7_s)
 RVVCALL(OPFVV1, vfrec7_v_d, OP_UU_D, H8, H8, frec7_d)
+GEN_VEXT_V_ENV(vfrec7_v_h_bf16, 2)
 GEN_VEXT_V_ENV(vfrec7_v_h, 2)
 GEN_VEXT_V_ENV(vfrec7_v_w, 4)
 GEN_VEXT_V_ENV(vfrec7_v_d, 8)
 
 /* Vector Floating-Point MIN/MAX Instructions */
+RVVCALL(OPFVV2, vfmin_vv_h_bf16, OP_UUU_H, H2, H2, H2, bfloat16_minimum_number)
 RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minimum_number)
 RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minimum_number)
 RVVCALL(OPFVV2, vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minimum_number)
+GEN_VEXT_VV_ENV(vfmin_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfmin_vv_h, 2)
 GEN_VEXT_VV_ENV(vfmin_vv_w, 4)
 GEN_VEXT_VV_ENV(vfmin_vv_d, 8)
+RVVCALL(OPFVF2, vfmin_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_minimum_number)
 RVVCALL(OPFVF2, vfmin_vf_h, OP_UUU_H, H2, H2, float16_minimum_number)
 RVVCALL(OPFVF2, vfmin_vf_w, OP_UUU_W, H4, H4, float32_minimum_number)
 RVVCALL(OPFVF2, vfmin_vf_d, OP_UUU_D, H8, H8, float64_minimum_number)
+GEN_VEXT_VF(vfmin_vf_h_bf16, 2)
 GEN_VEXT_VF(vfmin_vf_h, 2)
 GEN_VEXT_VF(vfmin_vf_w, 4)
 GEN_VEXT_VF(vfmin_vf_d, 8)
 
+RVVCALL(OPFVV2, vfmax_vv_h_bf16, OP_UUU_H, H2, H2, H2, bfloat16_maximum_number)
 RVVCALL(OPFVV2, vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maximum_number)
 RVVCALL(OPFVV2, vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maximum_number)
 RVVCALL(OPFVV2, vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maximum_number)
+GEN_VEXT_VV_ENV(vfmax_vv_h_bf16, 2)
 GEN_VEXT_VV_ENV(vfmax_vv_h, 2)
 GEN_VEXT_VV_ENV(vfmax_vv_w, 4)
 GEN_VEXT_VV_ENV(vfmax_vv_d, 8)
+RVVCALL(OPFVF2, vfmax_vf_h_bf16, OP_UUU_H, H2, H2, bfloat16_maximum_number)
 RVVCALL(OPFVF2, vfmax_vf_h, OP_UUU_H, H2, H2, float16_maximum_number)
 RVVCALL(OPFVF2, vfmax_vf_w, OP_UUU_W, H4, H4, float32_maximum_number)
 RVVCALL(OPFVF2, vfmax_vf_d, OP_UUU_D, H8, H8, float64_maximum_number)
+GEN_VEXT_VF(vfmax_vf_h_bf16, 2)
 GEN_VEXT_VF(vfmax_vf_h, 2)
 GEN_VEXT_VF(vfmax_vf_w, 4)
 GEN_VEXT_VF(vfmax_vf_d, 8)
@@ -4343,6 +4614,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,   \
     }                                                         \
 }
 
+GEN_VEXT_CMP_VV_ENV(vmfeq_vv_h_bf16, uint16_t, H2, bfloat16_eq_quiet)
 GEN_VEXT_CMP_VV_ENV(vmfeq_vv_h, uint16_t, H2, float16_eq_quiet)
 GEN_VEXT_CMP_VV_ENV(vmfeq_vv_w, uint32_t, H4, float32_eq_quiet)
 GEN_VEXT_CMP_VV_ENV(vmfeq_vv_d, uint64_t, H8, float64_eq_quiet)
@@ -4384,10 +4656,17 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2,       \
     }                                                               \
 }
 
+GEN_VEXT_CMP_VF(vmfeq_vf_h_bf16, uint16_t, H2, bfloat16_eq_quiet)
 GEN_VEXT_CMP_VF(vmfeq_vf_h, uint16_t, H2, float16_eq_quiet)
 GEN_VEXT_CMP_VF(vmfeq_vf_w, uint32_t, H4, float32_eq_quiet)
 GEN_VEXT_CMP_VF(vmfeq_vf_d, uint64_t, H8, float64_eq_quiet)
 
+static bool vmfne16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+    FloatRelation compare = bfloat16_compare_quiet(a, b, s);
+    return compare != float_relation_equal;
+}
+
 static bool vmfne16(uint16_t a, uint16_t b, float_status *s)
 {
     FloatRelation compare = float16_compare_quiet(a, b, s);
@@ -4406,27 +4685,39 @@ static bool vmfne64(uint64_t a, uint64_t b, float_status *s)
     return compare != float_relation_equal;
 }
 
+GEN_VEXT_CMP_VV_ENV(vmfne_vv_h_bf16, uint16_t, H2, vmfne16_bf16)
 GEN_VEXT_CMP_VV_ENV(vmfne_vv_h, uint16_t, H2, vmfne16)
 GEN_VEXT_CMP_VV_ENV(vmfne_vv_w, uint32_t, H4, vmfne32)
 GEN_VEXT_CMP_VV_ENV(vmfne_vv_d, uint64_t, H8, vmfne64)
+GEN_VEXT_CMP_VF(vmfne_vf_h_bf16, uint16_t, H2, vmfne16_bf16)
 GEN_VEXT_CMP_VF(vmfne_vf_h, uint16_t, H2, vmfne16)
 GEN_VEXT_CMP_VF(vmfne_vf_w, uint32_t, H4, vmfne32)
 GEN_VEXT_CMP_VF(vmfne_vf_d, uint64_t, H8, vmfne64)
 
+GEN_VEXT_CMP_VV_ENV(vmflt_vv_h_bf16, uint16_t, H2, bfloat16_lt)
 GEN_VEXT_CMP_VV_ENV(vmflt_vv_h, uint16_t, H2, float16_lt)
 GEN_VEXT_CMP_VV_ENV(vmflt_vv_w, uint32_t, H4, float32_lt)
 GEN_VEXT_CMP_VV_ENV(vmflt_vv_d, uint64_t, H8, float64_lt)
+GEN_VEXT_CMP_VF(vmflt_vf_h_bf16, uint16_t, H2, bfloat16_lt)
 GEN_VEXT_CMP_VF(vmflt_vf_h, uint16_t, H2, float16_lt)
 GEN_VEXT_CMP_VF(vmflt_vf_w, uint32_t, H4, float32_lt)
 GEN_VEXT_CMP_VF(vmflt_vf_d, uint64_t, H8, float64_lt)
 
+GEN_VEXT_CMP_VV_ENV(vmfle_vv_h_bf16, uint16_t, H2, bfloat16_le)
 GEN_VEXT_CMP_VV_ENV(vmfle_vv_h, uint16_t, H2, float16_le)
 GEN_VEXT_CMP_VV_ENV(vmfle_vv_w, uint32_t, H4, float32_le)
 GEN_VEXT_CMP_VV_ENV(vmfle_vv_d, uint64_t, H8, float64_le)
+GEN_VEXT_CMP_VF(vmfle_vf_h_bf16, uint16_t, H2, bfloat16_le)
 GEN_VEXT_CMP_VF(vmfle_vf_h, uint16_t, H2, float16_le)
 GEN_VEXT_CMP_VF(vmfle_vf_w, uint32_t, H4, float32_le)
 GEN_VEXT_CMP_VF(vmfle_vf_d, uint64_t, H8, float64_le)
 
+static bool vmfgt16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+    FloatRelation compare = bfloat16_compare(a, b, s);
+    return compare == float_relation_greater;
+}
+
 static bool vmfgt16(uint16_t a, uint16_t b, float_status *s)
 {
     FloatRelation compare = float16_compare(a, b, s);
@@ -4445,10 +4736,18 @@ static bool vmfgt64(uint64_t a, uint64_t b, float_status *s)
     return compare == float_relation_greater;
 }
 
+GEN_VEXT_CMP_VF(vmfgt_vf_h_bf16, uint16_t, H2, vmfgt16_bf16)
 GEN_VEXT_CMP_VF(vmfgt_vf_h, uint16_t, H2, vmfgt16)
 GEN_VEXT_CMP_VF(vmfgt_vf_w, uint32_t, H4, vmfgt32)
 GEN_VEXT_CMP_VF(vmfgt_vf_d, uint64_t, H8, vmfgt64)
 
+static bool vmfge16_bf16(uint16_t a, uint16_t b, float_status *s)
+{
+    FloatRelation compare = bfloat16_compare(a, b, s);
+    return compare == float_relation_greater ||
+           compare == float_relation_equal;
+}
+
 static bool vmfge16(uint16_t a, uint16_t b, float_status *s)
 {
     FloatRelation compare = float16_compare(a, b, s);
@@ -4470,11 +4769,31 @@ static bool vmfge64(uint64_t a, uint64_t b, float_status *s)
            compare == float_relation_equal;
 }
 
+GEN_VEXT_CMP_VF(vmfge_vf_h_bf16, uint16_t, H2, vmfge16_bf16)
 GEN_VEXT_CMP_VF(vmfge_vf_h, uint16_t, H2, vmfge16)
 GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
 GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
 
 /* Vector Floating-Point Classify Instruction */
+target_ulong fclass_h_bf16(uint64_t frs1)
+{
+    bfloat16 f = frs1;
+    bool sign = bfloat16_is_neg(f);
+
+    if (bfloat16_is_infinity(f)) {
+        return sign ? 1 << 0 : 1 << 7;
+    } else if (bfloat16_is_zero(f)) {
+        return sign ? 1 << 3 : 1 << 4;
+    } else if (bfloat16_is_zero_or_denormal(f)) {
+        return sign ? 1 << 2 : 1 << 5;
+    } else if (bfloat16_is_any_nan(f)) {
+        float_status s = { }; /* for snan_bit_is_one */
+        return bfloat16_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
+    } else {
+        return sign ? 1 << 1 : 1 << 6;
+    }
+}
+
 target_ulong fclass_h(uint64_t frs1)
 {
     float16 f = frs1;
@@ -4532,9 +4851,11 @@ target_ulong fclass_d(uint64_t frs1)
     }
 }
 
+RVVCALL(OPIVV1, vfclass_v_h_bf16, OP_UU_H, H2, H2, fclass_h_bf16)
 RVVCALL(OPIVV1, vfclass_v_h, OP_UU_H, H2, H2, fclass_h)
 RVVCALL(OPIVV1, vfclass_v_w, OP_UU_W, H4, H4, fclass_s)
 RVVCALL(OPIVV1, vfclass_v_d, OP_UU_D, H8, H8, fclass_d)
+GEN_VEXT_V(vfclass_v_h_bf16, 2)
 GEN_VEXT_V(vfclass_v_h, 2)
 GEN_VEXT_V(vfclass_v_w, 4)
 GEN_VEXT_V(vfclass_v_d, 8)
@@ -4625,17 +4946,21 @@ GEN_VEXT_V_ENV(vfwcvt_x_f_v_w, 8)
  * vfwcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to double-width float.
  */
 RVVCALL(OPFVV1, vfwcvt_f_xu_v_b, WOP_UU_B, H2, H1, uint8_to_float16)
+RVVCALL(OPFVV1, vfwcvt_f_xu_v_b_bf16, WOP_UU_B, H2, H1, uint8_to_bfloat16)
 RVVCALL(OPFVV1, vfwcvt_f_xu_v_h, WOP_UU_H, H4, H2, uint16_to_float32)
 RVVCALL(OPFVV1, vfwcvt_f_xu_v_w, WOP_UU_W, H8, H4, uint32_to_float64)
 GEN_VEXT_V_ENV(vfwcvt_f_xu_v_b, 2)
+GEN_VEXT_V_ENV(vfwcvt_f_xu_v_b_bf16, 2)
 GEN_VEXT_V_ENV(vfwcvt_f_xu_v_h, 4)
 GEN_VEXT_V_ENV(vfwcvt_f_xu_v_w, 8)
 
 /* vfwcvt.f.x.v vd, vs2, vm # Convert integer to double-width float. */
 RVVCALL(OPFVV1, vfwcvt_f_x_v_b, WOP_UU_B, H2, H1, int8_to_float16)
+RVVCALL(OPFVV1, vfwcvt_f_x_v_b_bf16, WOP_UU_B, H2, H1, int8_to_bfloat16)
 RVVCALL(OPFVV1, vfwcvt_f_x_v_h, WOP_UU_H, H4, H2, int16_to_float32)
 RVVCALL(OPFVV1, vfwcvt_f_x_v_w, WOP_UU_W, H8, H4, int32_to_float64)
 GEN_VEXT_V_ENV(vfwcvt_f_x_v_b, 2)
+GEN_VEXT_V_ENV(vfwcvt_f_x_v_b_bf16, 2)
 GEN_VEXT_V_ENV(vfwcvt_f_x_v_h, 4)
 GEN_VEXT_V_ENV(vfwcvt_f_x_v_w, 8)
 
@@ -4662,17 +4987,21 @@ GEN_VEXT_V_ENV(vfwcvtbf16_f_f_v, 4)
 #define NOP_UU_W uint32_t, uint64_t, uint64_t
 /* vfncvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */
 RVVCALL(OPFVV1, vfncvt_xu_f_w_b, NOP_UU_B, H1, H2, float16_to_uint8)
+RVVCALL(OPFVV1, vfncvt_xu_f_w_b_bf16, NOP_UU_B, H1, H2, bfloat16_to_uint8)
 RVVCALL(OPFVV1, vfncvt_xu_f_w_h, NOP_UU_H, H2, H4, float32_to_uint16)
 RVVCALL(OPFVV1, vfncvt_xu_f_w_w, NOP_UU_W, H4, H8, float64_to_uint32)
 GEN_VEXT_V_ENV(vfncvt_xu_f_w_b, 1)
+GEN_VEXT_V_ENV(vfncvt_xu_f_w_b_bf16, 1)
 GEN_VEXT_V_ENV(vfncvt_xu_f_w_h, 2)
 GEN_VEXT_V_ENV(vfncvt_xu_f_w_w, 4)
 
 /* vfncvt.x.f.v vd, vs2, vm # Convert double-width float to signed integer. */
 RVVCALL(OPFVV1, vfncvt_x_f_w_b, NOP_UU_B, H1, H2, float16_to_int8)
+RVVCALL(OPFVV1, vfncvt_x_f_w_b_bf16, NOP_UU_B, H1, H2, bfloat16_to_int8)
 RVVCALL(OPFVV1, vfncvt_x_f_w_h, NOP_UU_H, H2, H4, float32_to_int16)
 RVVCALL(OPFVV1, vfncvt_x_f_w_w, NOP_UU_W, H4, H8, float64_to_int32)
 GEN_VEXT_V_ENV(vfncvt_x_f_w_b, 1)
+GEN_VEXT_V_ENV(vfncvt_x_f_w_b_bf16, 1)
 GEN_VEXT_V_ENV(vfncvt_x_f_w_h, 2)
 GEN_VEXT_V_ENV(vfncvt_x_f_w_w, 4)
 
-- 
2.52.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH v5 9/9] target/riscv: Expose Zvfbfa extension as an experimental cpu property
  2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
                   ` (7 preceding siblings ...)
  2026-03-06  7:11 ` [PATCH v5 8/9] target/riscv: rvv: Support Zvfbfa vector bf16 operations Max Chou
@ 2026-03-06  7:11 ` Max Chou
  2026-03-09  4:51 ` [PATCH v5 0/9] Add Zvfbfa extension support Alistair Francis
  9 siblings, 0 replies; 28+ messages in thread
From: Max Chou @ 2026-03-06  7:11 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu, Max Chou

Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
Signed-off-by: Max Chou <max.chou@sifive.com>
---
 target/riscv/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 376517755e..73cfcbdf6f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1379,6 +1379,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
 /* These are experimental so mark with 'x-' */
 const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
     MULTI_EXT_CFG_BOOL("x-svukte", ext_svukte, false),
+    MULTI_EXT_CFG_BOOL("x-zvfbfa", ext_zvfbfa, false),
 
     { },
 };
-- 
2.52.0



^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 1/9] target/riscv: Add cfg properties for Zvfbfa extensions
  2026-03-06  7:10 ` [PATCH v5 1/9] target/riscv: Add cfg properties for Zvfbfa extensions Max Chou
@ 2026-03-09  4:44   ` Alistair Francis
  0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2026-03-09  4:44 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu,
	Daniel Henrique Barboza, Nutty Liu

On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
>
> The Zvfbfa extension adds more complete BF16 vector compute support
> and requires the Zve32f and Zfbfmin extensions.
>
> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Max Chou <max.chou@sifive.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.c                | 1 +
>  target/riscv/cpu_cfg_fields.h.inc | 1 +
>  target/riscv/tcg/tcg-cpu.c        | 8 ++++++++
>  3 files changed, 10 insertions(+)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9be79622f4..2ddc26c837 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -189,6 +189,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
>      ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
>      ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
>      ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
> +    ISA_EXT_DATA_ENTRY(zvfbfa, PRIV_VERSION_1_13_0, ext_zvfbfa),
>      ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
>      ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
>      ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
> diff --git a/target/riscv/cpu_cfg_fields.h.inc b/target/riscv/cpu_cfg_fields.h.inc
> index 70ec650abf..3696f02ee0 100644
> --- a/target/riscv/cpu_cfg_fields.h.inc
> +++ b/target/riscv/cpu_cfg_fields.h.inc
> @@ -99,6 +99,7 @@ BOOL_FIELD(ext_zvks)
>  BOOL_FIELD(ext_zvksc)
>  BOOL_FIELD(ext_zvksg)
>  BOOL_FIELD(ext_zmmul)
> +BOOL_FIELD(ext_zvfbfa)
>  BOOL_FIELD(ext_zvfbfmin)
>  BOOL_FIELD(ext_zvfbfwma)
>  BOOL_FIELD(ext_zvfh)
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 988b2d905f..720ff0c2a3 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -720,6 +720,14 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
>          return;
>      }
>
> +    if (cpu->cfg.ext_zvfbfa) {
> +        if (!cpu->cfg.ext_zve32f || !cpu->cfg.ext_zfbfmin) {
> +            error_setg(errp, "Zvfbfa extension requires Zve32f extension "
> +                             "and Zfbfmin extension");
> +            return;
> +        }
> +    }
> +
>      if ((cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinxmin) && !cpu->cfg.ext_zfinx) {
>          error_setg(errp, "Zdinx/Zhinx/Zhinxmin extensions require Zfinx");
>          return;
> --
> 2.52.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 2/9] target/riscv: Add the Zvfbfa extension implied rule
  2026-03-06  7:10 ` [PATCH v5 2/9] target/riscv: Add the Zvfbfa extension implied rule Max Chou
@ 2026-03-09  4:45   ` Alistair Francis
  0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2026-03-09  4:45 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu,
	Daniel Henrique Barboza, Nutty Liu

On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
>
> According to the Zvfbfa isa spec:
> The Zvfbfa extension requires the Zve32f and Zfbfmin extensions.
>
> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Max Chou <max.chou@sifive.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 2ddc26c837..376517755e 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -2619,6 +2619,15 @@ static RISCVCPUImpliedExtsRule SSCTR_IMPLIED = {
>      },
>  };
>
> +static RISCVCPUImpliedExtsRule ZVFBFA_IMPLIED = {
> +    .ext = CPU_CFG_OFFSET(ext_zvfbfa),
> +    .implied_multi_exts = {
> +        CPU_CFG_OFFSET(ext_zve32f), CPU_CFG_OFFSET(ext_zfbfmin),
> +
> +        RISCV_IMPLIED_EXTS_RULE_END
> +    },
> +};
> +
>  RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[] = {
>      &RVA_IMPLIED, &RVD_IMPLIED, &RVF_IMPLIED,
>      &RVM_IMPLIED, &RVV_IMPLIED, NULL
> @@ -2632,8 +2641,8 @@ RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[] = {
>      &ZHINX_IMPLIED, &ZHINXMIN_IMPLIED, &ZICNTR_IMPLIED,
>      &ZIHPM_IMPLIED, &ZK_IMPLIED, &ZKN_IMPLIED,
>      &ZKS_IMPLIED, &ZVBB_IMPLIED, &ZVE32F_IMPLIED,
> -    &ZVE32X_IMPLIED, &ZVE64D_IMPLIED, &ZVE64F_IMPLIED,
> -    &ZVE64X_IMPLIED, &ZVFBFMIN_IMPLIED, &ZVFBFWMA_IMPLIED,
> +    &ZVE32X_IMPLIED, &ZVE64D_IMPLIED, &ZVE64F_IMPLIED, &ZVE64X_IMPLIED,
> +    &ZVFBFA_IMPLIED, &ZVFBFMIN_IMPLIED, &ZVFBFWMA_IMPLIED,
>      &ZVFH_IMPLIED, &ZVFHMIN_IMPLIED, &ZVKN_IMPLIED,
>      &ZVKNC_IMPLIED, &ZVKNG_IMPLIED, &ZVKNHB_IMPLIED,
>      &ZVKS_IMPLIED,  &ZVKSC_IMPLIED, &ZVKSG_IMPLIED, &SSCFG_IMPLIED,
> --
> 2.52.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 0/9] Add Zvfbfa extension support
  2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
                   ` (8 preceding siblings ...)
  2026-03-06  7:11 ` [PATCH v5 9/9] target/riscv: Expose Zvfbfa extension as an experimental cpu property Max Chou
@ 2026-03-09  4:51 ` Alistair Francis
  2026-03-12 11:16   ` Max Chou
  9 siblings, 1 reply; 28+ messages in thread
From: Alistair Francis @ 2026-03-09  4:51 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
>
> This patch series adds support for the RISC-V Zvfbfa extension, which
> provides additional BF16 vector compute support.
>
> The isa spec of Zvfbfa extension is not ratified yet, so this patch
> series is based on the latest draft of the spec (v0.1) and make the
> Zvfbfa extension as an experimental extension.

It's not only not ratified, there isn't even a draft spec. A personal
GitHub repo without any tags or releases is not enough for us to take
this unfortunately.

>
> The Zvfbfa extension adds a 1-bit field, altfmt, to the vtype CSR in
> bit position 8.
> The Zvfbfa extension requires the Zve32f and Zfbfmin extensions.
>
> Specification:
> https://github.com/aswaterman/riscv-misc/blob/main/isa/zvfbfa.adoc

Overall this looks ok. Once a draft spec is released we can apply it

Alistair

>
> Changes in v5:
> - Fix typo in patch 1/5/8
> - Remove unnecessary do_bf16_nanbox
>
> Changes in v4:
> - Rebase on riscv-to-apply.next (commit 21101a7)
> - Update commit message of patch 2 (target/riscv: Add the Zvfbfa
>   extension implied rule)
> - Update checking flow of illegal ALTFMT SEW patterns at patch 3
>   (target/riscv: rvv: Add new VTYPE CSR field - altfmt)
>
> Changes in v3:
> - Rebased on riscv-to-apply.next (commit f66f234)
> - Fix typo in v2 patch 5 commit message
>
> Changes from v2:
> - Removed RFC designation from the series
> - Updated commit message for patch 3 (VTYPE CSR field -
>   altfmt) to clearly explain:
>   * VEDIV field removal (bits 8-9) since EDIV extension is not
>     planned to be part of the base V extension
>   * ALTFMT field addition at bit 8
>   * RESERVED field change from bit 10 to bit 9
> - Added new patch 4: Introduce reset_ill_vtype helper function to
>   consolidate illegal vtype CSR reset logic
>
> v4: <20260304132514.2889449-1-max.chou@sifive.com>
> v3: <20260127014227.406653-1-max.chou@sifive.com>
> v2: <20260108132631.9429-1-max.chou@sifive.com>
> v1: <20250915084037.1816893-1-max.chou@sifive.com>
>
> rnax
>
>
> Max Chou (9):
>   target/riscv: Add cfg properties for Zvfbfa extensions
>   target/riscv: Add the Zvfbfa extension implied rule
>   target/riscv: rvv: Add new VTYPE CSR field - altfmt
>   target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype
>     CSR
>   target/riscv: Use the tb->cs_base as the extend tb flags
>   target/riscv: Introduce altfmt into DisasContext
>   target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension
>   target/riscv: rvv: Support Zvfbfa vector bf16 operations
>   target/riscv: Expose Zvfbfa extension as an experimental cpu property
>
>  include/exec/translation-block.h        |   1 +
>  target/riscv/cpu.c                      |  15 +-
>  target/riscv/cpu.h                      |   7 +-
>  target/riscv/cpu_cfg_fields.h.inc       |   1 +
>  target/riscv/helper.h                   |  60 ++
>  target/riscv/insn_trans/trans_rvv.c.inc | 988 +++++++++++++++---------
>  target/riscv/internals.h                |   1 +
>  target/riscv/tcg/tcg-cpu.c              |  15 +-
>  target/riscv/translate.c                |  11 +
>  target/riscv/vector_helper.c            | 389 +++++++++-
>  10 files changed, 1088 insertions(+), 400 deletions(-)
>
> --
> 2.52.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 3/9] target/riscv: rvv: Add new VTYPE CSR field - altfmt
  2026-03-06  7:10 ` [PATCH v5 3/9] target/riscv: rvv: Add new VTYPE CSR field - altfmt Max Chou
@ 2026-03-09  4:55   ` Alistair Francis
  2026-03-16  9:20   ` Nutty.Liu
  1 sibling, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2026-03-09  4:55 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu,
	Daniel Henrique Barboza

On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
>
> According to the Zvfbfa ISA spec v0.1, the vtype CSR adds a new field:
> altfmt for BF16 support.
> This update changes the layout of the vtype CSR fields.
>
> - Removed VEDIV field (bits 8-9) since EDIV extension is not planned to
>   be part of the base V extension
> - Added ALTFMT field at bit 8
> - Changed RESERVED field to start from bit 9 instead of bit 10
>
> When Zvfbfa is disabled, bits 8+ are treated as reserved (preserving
> existing behavior for altfmt bit). When Zvfbfa is enabled, only bits 9+
> are reserved.
>
> Reference:
> - https://github.com/riscvarchive/riscv-v-spec/blob/master/ediv.adoc
>
> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Max Chou <max.chou@sifive.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.h           |  4 ++--
>  target/riscv/vector_helper.c | 39 +++++++++++++++++++++++++++++++-----
>  2 files changed, 36 insertions(+), 7 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 35d1f6362c..962cc45073 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -191,8 +191,8 @@ FIELD(VTYPE, VLMUL, 0, 3)
>  FIELD(VTYPE, VSEW, 3, 3)
>  FIELD(VTYPE, VTA, 6, 1)
>  FIELD(VTYPE, VMA, 7, 1)
> -FIELD(VTYPE, VEDIV, 8, 2)
> -FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
> +FIELD(VTYPE, ALTFMT, 8, 1)
> +FIELD(VTYPE, RESERVED, 9, sizeof(target_ulong) * 8 - 10)
>
>  typedef struct PMUCTRState {
>      /* Current value of a counter */
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index caa8dd9c12..7575e24084 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -33,6 +33,22 @@
>  #include "vector_internals.h"
>  #include <math.h>
>
> +static target_ulong vtype_reserved(CPURISCVState *env, target_ulong vtype)
> +{
> +    int xlen = riscv_cpu_xlen(env);
> +    target_ulong reserved = 0;
> +
> +    if (riscv_cpu_cfg(env)->ext_zvfbfa) {
> +        reserved = vtype & MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
> +                                           xlen - 1 - R_VTYPE_RESERVED_SHIFT);
> +    } else {
> +        reserved = vtype & MAKE_64BIT_MASK(R_VTYPE_ALTFMT_SHIFT,
> +                                           xlen - 1 - R_VTYPE_ALTFMT_SHIFT);
> +    }
> +
> +    return reserved;
> +}
> +
>  target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>                              target_ulong s2, target_ulong x0)
>  {
> @@ -41,12 +57,10 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>      uint64_t vlmul = FIELD_EX64(s2, VTYPE, VLMUL);
>      uint8_t vsew = FIELD_EX64(s2, VTYPE, VSEW);
>      uint16_t sew = 8 << vsew;
> -    uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
> +    uint8_t altfmt = FIELD_EX64(s2, VTYPE, ALTFMT);
> +    bool ill_altfmt = true;
>      int xlen = riscv_cpu_xlen(env);
>      bool vill = (s2 >> (xlen - 1)) & 0x1;
> -    target_ulong reserved = s2 &
> -                            MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
> -                                            xlen - 1 - R_VTYPE_RESERVED_SHIFT);
>      uint16_t vlen = cpu->cfg.vlenb << 3;
>      int8_t lmul;
>
> @@ -63,7 +77,22 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>          }
>      }
>
> -    if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
> +    switch (vsew) {
> +    case MO_8:
> +        ill_altfmt &= !(cpu->cfg.ext_zvfbfa);
> +        break;
> +    case MO_16:
> +        ill_altfmt &= !(cpu->cfg.ext_zvfbfa);
> +        break;
> +    default:
> +        break;
> +    }
> +
> +    if (altfmt && ill_altfmt) {
> +        vill = true;
> +    }
> +
> +    if ((sew > cpu->cfg.elen) || vill || (vtype_reserved(env, s2) != 0)) {
>          /* only set vill bit. */
>          env->vill = 1;
>          env->vtype = 0;
> --
> 2.52.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 4/9] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR
  2026-03-06  7:10 ` [PATCH v5 4/9] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR Max Chou
@ 2026-03-09  4:55   ` Alistair Francis
  2026-03-16  9:22   ` Nutty.Liu
  1 sibling, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2026-03-09  4:55 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
>
> Replace the same vill reset flow by reset_ill_vtype function.
>
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Max Chou <max.chou@sifive.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/vector_helper.c | 21 +++++++++++----------
>  1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 7575e24084..b7105627ed 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -49,6 +49,15 @@ static target_ulong vtype_reserved(CPURISCVState *env, target_ulong vtype)
>      return reserved;
>  }
>
> +static inline void reset_ill_vtype(CPURISCVState *env)
> +{
> +    /* only set vill bit. */
> +    env->vill = 1;
> +    env->vtype = 0;
> +    env->vl = 0;
> +    env->vstart = 0;
> +}
> +
>  target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>                              target_ulong s2, target_ulong x0)
>  {
> @@ -93,11 +102,7 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>      }
>
>      if ((sew > cpu->cfg.elen) || vill || (vtype_reserved(env, s2) != 0)) {
> -        /* only set vill bit. */
> -        env->vill = 1;
> -        env->vtype = 0;
> -        env->vl = 0;
> -        env->vstart = 0;
> +        reset_ill_vtype(env);
>          return 0;
>      }
>
> @@ -113,11 +118,7 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>      }
>
>      if (cpu->cfg.rvv_vsetvl_x0_vill && x0 && (env->vl != vl)) {
> -        /* only set vill bit. */
> -        env->vill = 1;
> -        env->vtype = 0;
> -        env->vl = 0;
> -        env->vstart = 0;
> +        reset_ill_vtype(env);
>          return 0;
>      }
>
> --
> 2.52.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 5/9] target/riscv: Use the tb->cs_base as the extend tb flags
  2026-03-06  7:11 ` [PATCH v5 5/9] target/riscv: Use the tb->cs_base as the extend tb flags Max Chou
@ 2026-03-09  5:01   ` Alistair Francis
  2026-03-12 11:42     ` Max Chou
  0 siblings, 1 reply; 28+ messages in thread
From: Alistair Francis @ 2026-03-09  5:01 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
>
> We have more than 32-bits worth of state per TB, so use the
> tb->cs_base, which is otherwise unused for RISC-V, as the extend flag.
>
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Max Chou <max.chou@sifive.com>
> ---
>  include/exec/translation-block.h | 1 +
>  target/riscv/cpu.h               | 3 +++
>  target/riscv/tcg/tcg-cpu.c       | 7 ++++++-
>  3 files changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h
> index 4f83d5bec9..40cc699031 100644
> --- a/include/exec/translation-block.h
> +++ b/include/exec/translation-block.h
> @@ -65,6 +65,7 @@ struct TranslationBlock {
>       * arm: an extension of tb->flags,
>       * s390x: instruction data for EXECUTE,
>       * sparc: the next pc of the instruction queue (for delay slots).
> +     * riscv: an extension of tb->flags,
>       */
>      uint64_t cs_base;
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 962cc45073..4c0676ed53 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -703,6 +703,9 @@ FIELD(TB_FLAGS, BCFI_ENABLED, 28, 1)
>  FIELD(TB_FLAGS, PM_PMM, 29, 2)
>  FIELD(TB_FLAGS, PM_SIGNEXTEND, 31, 1)
>
> +FIELD(EXT_TB_FLAGS, MISA_EXT, 0, 32)
> +FIELD(EXT_TB_FLAGS, ALTFMT, 32, 1)
> +
>  #ifdef TARGET_RISCV32
>  #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
>  #else
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index 720ff0c2a3..378b298886 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -104,6 +104,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
>      RISCVCPU *cpu = env_archcpu(env);
>      RISCVExtStatus fs, vs;
>      uint32_t flags = 0;
> +    uint64_t ext_flags = 0;
>      bool pm_signext = riscv_cpu_virt_mem_enabled(env);
>
>      if (cpu->cfg.ext_zve32x) {
> @@ -118,6 +119,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
>
>          /* lmul encoded as in DisasContext::lmul */
>          int8_t lmul = sextract32(FIELD_EX64(env->vtype, VTYPE, VLMUL), 0, 3);
> +        uint8_t altfmt = FIELD_EX64(env->vtype, VTYPE, ALTFMT);
>          uint32_t vsew = FIELD_EX64(env->vtype, VTYPE, VSEW);
>          uint32_t vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul);
>          uint32_t maxsz = vlmax << vsew;
> @@ -133,6 +135,7 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
>          flags = FIELD_DP32(flags, TB_FLAGS, VMA,
>                             FIELD_EX64(env->vtype, VTYPE, VMA));
>          flags = FIELD_DP32(flags, TB_FLAGS, VSTART_EQ_ZERO, env->vstart == 0);
> +        ext_flags = FIELD_DP64(ext_flags, EXT_TB_FLAGS, ALTFMT, altfmt);
>      } else {
>          flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
>      }
> @@ -189,10 +192,12 @@ static TCGTBCPUState riscv_get_tb_cpu_state(CPUState *cs)
>      flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env));
>      flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext);
>
> +    ext_flags = FIELD_DP64(ext_flags, EXT_TB_FLAGS, MISA_EXT, env->misa_ext);
> +
>      return (TCGTBCPUState){
>          .pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc,
>          .flags = flags,
> -        .cs_base = env->misa_ext,
> +        .cs_base = ext_flags,

We need to update the comment in `struct TranslationBlock` for
`target_ulong cs_base`

Alistair

>      };
>  }
>
> --
> 2.52.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 6/9] target/riscv: Introduce altfmt into DisasContext
  2026-03-06  7:11 ` [PATCH v5 6/9] target/riscv: Introduce altfmt into DisasContext Max Chou
@ 2026-03-09  5:02   ` Alistair Francis
  0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2026-03-09  5:02 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
>
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Max Chou <max.chou@sifive.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/translate.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index cb4f443601..89d4f6fe67 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -101,6 +101,7 @@ typedef struct DisasContext {
>      bool cfg_vta_all_1s;
>      bool vstart_eq_zero;
>      bool vl_eq_vlmax;
> +    bool altfmt;
>      CPUState *cs;
>      TCGv zero;
>      /* actual address width */
> @@ -1307,6 +1308,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>      RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
>      RISCVCPU *cpu = RISCV_CPU(cs);
>      uint32_t tb_flags = ctx->base.tb->flags;
> +    uint64_t ext_tb_flags = ctx->base.tb->cs_base;
>
>      ctx->pc_save = ctx->base.pc_first;
>      ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
> @@ -1326,6 +1328,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>      ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
>      ctx->vstart_eq_zero = FIELD_EX32(tb_flags, TB_FLAGS, VSTART_EQ_ZERO);
>      ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
> +    ctx->altfmt = FIELD_EX64(ext_tb_flags, EXT_TB_FLAGS, ALTFMT);
>      ctx->misa_mxl_max = mcc->def->misa_mxl_max;
>      ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
>      ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
> --
> 2.52.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 7/9] target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension
  2026-03-06  7:11 ` [PATCH v5 7/9] target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension Max Chou
@ 2026-03-09  5:04   ` Alistair Francis
  0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2026-03-09  5:04 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
>
> According to the Zvfbfa ISA spec (v0.1), improperly NaN-boxed
> f-register operands must substitute the BF16 canonical NaN instead of
> the FP16 canonical NaN for some vector floating-point instructions.
>
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Max Chou <max.chou@sifive.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 18 +++++++++---------
>  target/riscv/translate.c                |  8 ++++++++
>  2 files changed, 17 insertions(+), 9 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index 4df9a40b44..03ae85796a 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -2319,17 +2319,17 @@ GEN_OPIWI_NARROW_TRANS(vnclip_wi, IMM_ZX, vnclip_wx)
>   */
>  static void do_nanbox(DisasContext *s, TCGv_i64 out, TCGv_i64 in)
>  {
> -    switch (s->sew) {
> -    case 1:
> -        gen_check_nanbox_h(out, in);
> -        break;
> -    case 2:
> +    if (s->sew == MO_16) {
> +        if (s->altfmt) {
> +            gen_check_nanbox_h_bf16(out, in);
> +        } else {
> +            gen_check_nanbox_h(out, in);
> +        }
> +    } else if (s->sew == MO_32) {
>          gen_check_nanbox_s(out, in);
> -        break;
> -    case 3:
> +    } else if (s->sew == MO_64) {
>          tcg_gen_mov_i64(out, in);
> -        break;
> -    default:
> +    } else {
>          g_assert_not_reached();
>      }
>  }
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 89d4f6fe67..d9df6a35ca 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -214,6 +214,14 @@ static void gen_check_nanbox_h(TCGv_i64 out, TCGv_i64 in)
>      tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
>  }
>
> +static void gen_check_nanbox_h_bf16(TCGv_i64 out, TCGv_i64 in)
> +{
> +    TCGv_i64 t_max = tcg_constant_i64(0xffffffffffff0000ull);
> +    TCGv_i64 t_nan = tcg_constant_i64(0xffffffffffff7fc0ull);
> +
> +    tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
> +}
> +
>  static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
>  {
>      TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull);
> --
> 2.52.0
>
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 0/9] Add Zvfbfa extension support
  2026-03-09  4:51 ` [PATCH v5 0/9] Add Zvfbfa extension support Alistair Francis
@ 2026-03-12 11:16   ` Max Chou
  2026-03-13  1:09     ` Alistair Francis
  0 siblings, 1 reply; 28+ messages in thread
From: Max Chou @ 2026-03-12 11:16 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On 2026-03-09 14:51, Alistair Francis wrote:
> On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
> >
> > This patch series adds support for the RISC-V Zvfbfa extension, which
> > provides additional BF16 vector compute support.
> >
> > The isa spec of Zvfbfa extension is not ratified yet, so this patch
> > series is based on the latest draft of the spec (v0.1) and make the
> > Zvfbfa extension as an experimental extension.
> 
> It's not only not ratified, there isn't even a draft spec. A personal
> GitHub repo without any tags or releases is not enough for us to take
> this unfortunately.
> 
> >
> > The Zvfbfa extension adds a 1-bit field, altfmt, to the vtype CSR in
> > bit position 8.
> > The Zvfbfa extension requires the Zve32f and Zfbfmin extensions.
> >
> > Specification:
> > https://github.com/aswaterman/riscv-misc/blob/main/isa/zvfbfa.adoc
> 
> Overall this looks ok. Once a draft spec is released we can apply it
> 
> Alistair
> 

Hi Alistair,

Thanks for the review. You asked for a pointer to the standalone ISA
spec repo for Zvfbfa — I want to explain why that doesn’t exist and
where the spec lives instead.

RVIA changed the ISA development workflow: new ISA specifications are
no longer developed in standalone repositories. Instead, they are
developed as forked branches of the base ISA manual repo
(riscv/riscv-isa-manual) and merged into it upon ratification [1].

For Zvfbfa specifically, the official spec artifact under this new
workflow is a PR against riscv-isa-manual [2], incorporating the spec
text [3]. The PR notes that the spec has passed internal review and
ARC review, as documented in the tech-unprivileged list thread [4].

PR #2743 is currently open, meaning ratification is pending but not
yet complete. Under the new workflow, merge into main of
riscv-isa-manual is the signal that ratification is finalized. If you
prefer to wait until that merge happens before applying this patchset,
I completely understand. Alternatively, if you are comfortable
accepting it as ratification-pending, I am happy to address any
remaining technical comments.

Please let me know how you would like to proceed.

References:
[1] https://lists.riscv.org/g/sig-documentation/message/275
[2] https://github.com/riscv/riscv-isa-manual/pull/2743
[3] https://github.com/aswaterman/riscv-misc/blob/main/isa/zvfbfa.adoc
[4] https://lists.riscv.org/g/tech-unprivileged/message/1031
    https://lists.riscv.org/g/tech-unprivileged/message/1085
    https://lists.riscv.org/g/tech-unprivileged/message/1109

Best regards,
rnax



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 5/9] target/riscv: Use the tb->cs_base as the extend tb flags
  2026-03-09  5:01   ` Alistair Francis
@ 2026-03-12 11:42     ` Max Chou
  2026-03-13  0:59       ` Alistair Francis
  0 siblings, 1 reply; 28+ messages in thread
From: Max Chou @ 2026-03-12 11:42 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On 2026-03-09 15:01, Alistair Francis wrote:
> On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
> >
> > We have more than 32-bits worth of state per TB, so use the
> > tb->cs_base, which is otherwise unused for RISC-V, as the extend flag.
> >
> > Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> > Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> > Signed-off-by: Max Chou <max.chou@sifive.com>
> > ---
> >  include/exec/translation-block.h | 1 +
> >  target/riscv/cpu.h               | 3 +++
> >  target/riscv/tcg/tcg-cpu.c       | 7 ++++++-
> >  3 files changed, 10 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h
> > index 4f83d5bec9..40cc699031 100644
> > --- a/include/exec/translation-block.h
> > +++ b/include/exec/translation-block.h
> > @@ -65,6 +65,7 @@ struct TranslationBlock {
> >       * arm: an extension of tb->flags,
> >       * s390x: instruction data for EXECUTE,
> >       * sparc: the next pc of the instruction queue (for delay slots).
> > +     * riscv: an extension of tb->flags,
> >       */
> >      uint64_t cs_base;
> >
>

Hi Alistair,

I’m curious to know if you mean adding more details here, such as
specifying the bit width for misa (e.g., 32 bits) or the bit width for
ALTFMT (e.g., 1 bit).
If so, I’ll include these details in the v6 version.

Thanks,
rnax

> We need to update the comment in `struct TranslationBlock` for
> `target_ulong cs_base`
> 
> Alistair
> 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 5/9] target/riscv: Use the tb->cs_base as the extend tb flags
  2026-03-12 11:42     ` Max Chou
@ 2026-03-13  0:59       ` Alistair Francis
  0 siblings, 0 replies; 28+ messages in thread
From: Alistair Francis @ 2026-03-13  0:59 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On Thu, Mar 12, 2026 at 9:42 PM Max Chou <max.chou@sifive.com> wrote:
>
> On 2026-03-09 15:01, Alistair Francis wrote:
> > On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
> > >
> > > We have more than 32-bits worth of state per TB, so use the
> > > tb->cs_base, which is otherwise unused for RISC-V, as the extend flag.
> > >
> > > Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> > > Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> > > Signed-off-by: Max Chou <max.chou@sifive.com>
> > > ---
> > >  include/exec/translation-block.h | 1 +
> > >  target/riscv/cpu.h               | 3 +++
> > >  target/riscv/tcg/tcg-cpu.c       | 7 ++++++-
> > >  3 files changed, 10 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h
> > > index 4f83d5bec9..40cc699031 100644
> > > --- a/include/exec/translation-block.h
> > > +++ b/include/exec/translation-block.h
> > > @@ -65,6 +65,7 @@ struct TranslationBlock {
> > >       * arm: an extension of tb->flags,
> > >       * s390x: instruction data for EXECUTE,
> > >       * sparc: the next pc of the instruction queue (for delay slots).
> > > +     * riscv: an extension of tb->flags,
> > >       */
> > >      uint64_t cs_base;
> > >
> >
>
> Hi Alistair,
>
> I’m curious to know if you mean adding more details here, such as
> specifying the bit width for misa (e.g., 32 bits) or the bit width for
> ALTFMT (e.g., 1 bit).
> If so, I’ll include these details in the v6 version.

Oh! You did update the comment. Sorry I missed that.

No action required!

Alistair

>
> Thanks,
> rnax
>
> > We need to update the comment in `struct TranslationBlock` for
> > `target_ulong cs_base`
> >
> > Alistair
> >


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 0/9] Add Zvfbfa extension support
  2026-03-12 11:16   ` Max Chou
@ 2026-03-13  1:09     ` Alistair Francis
  2026-03-16  8:28       ` Max Chou
  0 siblings, 1 reply; 28+ messages in thread
From: Alistair Francis @ 2026-03-13  1:09 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On Thu, Mar 12, 2026 at 9:16 PM Max Chou <max.chou@sifive.com> wrote:
>
> On 2026-03-09 14:51, Alistair Francis wrote:
> > On Fri, Mar 6, 2026 at 5:13 PM Max Chou <max.chou@sifive.com> wrote:
> > >
> > > This patch series adds support for the RISC-V Zvfbfa extension, which
> > > provides additional BF16 vector compute support.
> > >
> > > The isa spec of Zvfbfa extension is not ratified yet, so this patch
> > > series is based on the latest draft of the spec (v0.1) and make the
> > > Zvfbfa extension as an experimental extension.
> >
> > It's not only not ratified, there isn't even a draft spec. A personal
> > GitHub repo without any tags or releases is not enough for us to take
> > this unfortunately.
> >
> > >
> > > The Zvfbfa extension adds a 1-bit field, altfmt, to the vtype CSR in
> > > bit position 8.
> > > The Zvfbfa extension requires the Zve32f and Zfbfmin extensions.
> > >
> > > Specification:
> > > https://github.com/aswaterman/riscv-misc/blob/main/isa/zvfbfa.adoc
> >
> > Overall this looks ok. Once a draft spec is released we can apply it
> >
> > Alistair
> >
>
> Hi Alistair,
>
> Thanks for the review. You asked for a pointer to the standalone ISA
> spec repo for Zvfbfa — I want to explain why that doesn’t exist and
> where the spec lives instead.
>
> RVIA changed the ISA development workflow: new ISA specifications are
> no longer developed in standalone repositories. Instead, they are
> developed as forked branches of the base ISA manual repo
> (riscv/riscv-isa-manual) and merged into it upon ratification [1].

That's fine. The details you point to show forking to a RISC-V org
GitHub account. In which case it's still clearly a RISC-V spec, under
RVI. As long as it's tagged for draft releases that isn't really any
different then before.

>
> For Zvfbfa specifically, the official spec artifact under this new
> workflow is a PR against riscv-isa-manual [2], incorporating the spec
> text [3]. The PR notes that the spec has passed internal review and
> ARC review, as documented in the tech-unprivileged list thread [4].

The problem here is that there is no version control. If we merge this
series and the PR changes then suddenly we are out of sync there is no
way to track which version of the draft spec we support.

We need clear versions, like we previously have. For example version
0.7 and then 0.8. Draft versions are ok, but we need a stable target
to develop against.

>
> PR #2743 is currently open, meaning ratification is pending but not
> yet complete. Under the new workflow, merge into main of
> riscv-isa-manual is the signal that ratification is finalized. If you
> prefer to wait until that merge happens before applying this patchset,
> I completely understand. Alternatively, if you are comfortable
> accepting it as ratification-pending, I am happy to address any
> remaining technical comments.

In this case we will have to wait as there is no stable version of the
spec to point to.

Alistair

>
> Please let me know how you would like to proceed.
>
> References:
> [1] https://lists.riscv.org/g/sig-documentation/message/275
> [2] https://github.com/riscv/riscv-isa-manual/pull/2743
> [3] https://github.com/aswaterman/riscv-misc/blob/main/isa/zvfbfa.adoc
> [4] https://lists.riscv.org/g/tech-unprivileged/message/1031
>     https://lists.riscv.org/g/tech-unprivileged/message/1085
>     https://lists.riscv.org/g/tech-unprivileged/message/1109
>
> Best regards,
> rnax
>


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 0/9] Add Zvfbfa extension support
  2026-03-13  1:09     ` Alistair Francis
@ 2026-03-16  8:28       ` Max Chou
  2026-03-19  3:45         ` Alistair Francis
  0 siblings, 1 reply; 28+ messages in thread
From: Max Chou @ 2026-03-16  8:28 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On 2026-03-13 11:09, Alistair Francis wrote:
> The problem here is that there is no version control. If we merge this
> series and the PR changes then suddenly we are out of sync there is no
> way to track which version of the draft spec we support.
> 
> We need clear versions, like we previously have. For example version
> 0.7 and then 0.8. Draft versions are ok, but we need a stable target
> to develop against.
> 
> >
> > PR #2743 is currently open, meaning ratification is pending but not
> > yet complete. Under the new workflow, merge into main of
> > riscv-isa-manual is the signal that ratification is finalized. If you
> > prefer to wait until that merge happens before applying this patchset,
> > I completely understand. Alternatively, if you are comfortable
> > accepting it as ratification-pending, I am happy to address any
> > remaining technical comments.
> 
> In this case we will have to wait as there is no stable version of the
> spec to point to.
> 
> Alistair
> 

Hi Alistair,

Thank you for your feedback on the version control and stability of the
Zvfbfa specification. I understand your concern about developing against
a moving target.

To address the lack of a stable target as you mentioned, I’d like to
help bridge this gap. Since this patchset was prepared based on the
Zvfbfa version v0.1 and this version has passed the ARC review, I
propose we coordinate with the Zvfbfa isa designer to check the
specific tag/commit ID of the Zvfbfa v0.1.
If we could create a tag or release for v0.1 (e.g., v0.1/v0.1-draft)
within the Zvfbfa repository that explicitly marks the current state of
the Zvfbfa spec, would that provide the necessary versioning baseline
for you to accept this patchset?

My goal is to ensure QEMU supports a traceable version of the draft spec
while respecting the current RVIA development process for this ISA
implementation patchset and the followings in the future.

rnax


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 3/9] target/riscv: rvv: Add new VTYPE CSR field - altfmt
  2026-03-06  7:10 ` [PATCH v5 3/9] target/riscv: rvv: Add new VTYPE CSR field - altfmt Max Chou
  2026-03-09  4:55   ` Alistair Francis
@ 2026-03-16  9:20   ` Nutty.Liu
  1 sibling, 0 replies; 28+ messages in thread
From: Nutty.Liu @ 2026-03-16  9:20 UTC (permalink / raw)
  To: Max Chou, qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu,
	Daniel Henrique Barboza


On 3/6/2026 3:10 PM, Max Chou wrote:
> According to the Zvfbfa ISA spec v0.1, the vtype CSR adds a new field:
> altfmt for BF16 support.
> This update changes the layout of the vtype CSR fields.
>
> - Removed VEDIV field (bits 8-9) since EDIV extension is not planned to
>    be part of the base V extension
> - Added ALTFMT field at bit 8
> - Changed RESERVED field to start from bit 9 instead of bit 10
>
> When Zvfbfa is disabled, bits 8+ are treated as reserved (preserving
> existing behavior for altfmt bit). When Zvfbfa is enabled, only bits 9+
> are reserved.
>
> Reference:
> - https://github.com/riscvarchive/riscv-v-spec/blob/master/ediv.adoc
>
> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>

Thanks,
Nutty
> ---
>   target/riscv/cpu.h           |  4 ++--
>   target/riscv/vector_helper.c | 39 +++++++++++++++++++++++++++++++-----
>   2 files changed, 36 insertions(+), 7 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 35d1f6362c..962cc45073 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -191,8 +191,8 @@ FIELD(VTYPE, VLMUL, 0, 3)
>   FIELD(VTYPE, VSEW, 3, 3)
>   FIELD(VTYPE, VTA, 6, 1)
>   FIELD(VTYPE, VMA, 7, 1)
> -FIELD(VTYPE, VEDIV, 8, 2)
> -FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
> +FIELD(VTYPE, ALTFMT, 8, 1)
> +FIELD(VTYPE, RESERVED, 9, sizeof(target_ulong) * 8 - 10)
>   
>   typedef struct PMUCTRState {
>       /* Current value of a counter */
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index caa8dd9c12..7575e24084 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -33,6 +33,22 @@
>   #include "vector_internals.h"
>   #include <math.h>
>   
> +static target_ulong vtype_reserved(CPURISCVState *env, target_ulong vtype)
> +{
> +    int xlen = riscv_cpu_xlen(env);
> +    target_ulong reserved = 0;
> +
> +    if (riscv_cpu_cfg(env)->ext_zvfbfa) {
> +        reserved = vtype & MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
> +                                           xlen - 1 - R_VTYPE_RESERVED_SHIFT);
> +    } else {
> +        reserved = vtype & MAKE_64BIT_MASK(R_VTYPE_ALTFMT_SHIFT,
> +                                           xlen - 1 - R_VTYPE_ALTFMT_SHIFT);
> +    }
> +
> +    return reserved;
> +}
> +
>   target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>                               target_ulong s2, target_ulong x0)
>   {
> @@ -41,12 +57,10 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>       uint64_t vlmul = FIELD_EX64(s2, VTYPE, VLMUL);
>       uint8_t vsew = FIELD_EX64(s2, VTYPE, VSEW);
>       uint16_t sew = 8 << vsew;
> -    uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
> +    uint8_t altfmt = FIELD_EX64(s2, VTYPE, ALTFMT);
> +    bool ill_altfmt = true;
>       int xlen = riscv_cpu_xlen(env);
>       bool vill = (s2 >> (xlen - 1)) & 0x1;
> -    target_ulong reserved = s2 &
> -                            MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
> -                                            xlen - 1 - R_VTYPE_RESERVED_SHIFT);
>       uint16_t vlen = cpu->cfg.vlenb << 3;
>       int8_t lmul;
>   
> @@ -63,7 +77,22 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>           }
>       }
>   
> -    if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
> +    switch (vsew) {
> +    case MO_8:
> +        ill_altfmt &= !(cpu->cfg.ext_zvfbfa);
> +        break;
> +    case MO_16:
> +        ill_altfmt &= !(cpu->cfg.ext_zvfbfa);
> +        break;
> +    default:
> +        break;
> +    }
> +
> +    if (altfmt && ill_altfmt) {
> +        vill = true;
> +    }
> +
> +    if ((sew > cpu->cfg.elen) || vill || (vtype_reserved(env, s2) != 0)) {
>           /* only set vill bit. */
>           env->vill = 1;
>           env->vtype = 0;


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 4/9] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR
  2026-03-06  7:10 ` [PATCH v5 4/9] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR Max Chou
  2026-03-09  4:55   ` Alistair Francis
@ 2026-03-16  9:22   ` Nutty.Liu
  1 sibling, 0 replies; 28+ messages in thread
From: Nutty.Liu @ 2026-03-16  9:22 UTC (permalink / raw)
  To: Max Chou, qemu-devel, qemu-riscv
  Cc: Palmer Dabbelt, Alistair Francis, Weiwei Li,
	Daniel Henrique Barboza, Liu Zhiwei, Chao Liu


On 3/6/2026 3:10 PM, Max Chou wrote:
> Replace the same vill reset flow by reset_ill_vtype function.
>
> Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com>
> Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>

Thanks,
Nutty
> ---
>   target/riscv/vector_helper.c | 21 +++++++++++----------
>   1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 7575e24084..b7105627ed 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -49,6 +49,15 @@ static target_ulong vtype_reserved(CPURISCVState *env, target_ulong vtype)
>       return reserved;
>   }
>   
> +static inline void reset_ill_vtype(CPURISCVState *env)
> +{
> +    /* only set vill bit. */
> +    env->vill = 1;
> +    env->vtype = 0;
> +    env->vl = 0;
> +    env->vstart = 0;
> +}
> +
>   target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>                               target_ulong s2, target_ulong x0)
>   {
> @@ -93,11 +102,7 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>       }
>   
>       if ((sew > cpu->cfg.elen) || vill || (vtype_reserved(env, s2) != 0)) {
> -        /* only set vill bit. */
> -        env->vill = 1;
> -        env->vtype = 0;
> -        env->vl = 0;
> -        env->vstart = 0;
> +        reset_ill_vtype(env);
>           return 0;
>       }
>   
> @@ -113,11 +118,7 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>       }
>   
>       if (cpu->cfg.rvv_vsetvl_x0_vill && x0 && (env->vl != vl)) {
> -        /* only set vill bit. */
> -        env->vill = 1;
> -        env->vtype = 0;
> -        env->vl = 0;
> -        env->vstart = 0;
> +        reset_ill_vtype(env);
>           return 0;
>       }
>   


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 0/9] Add Zvfbfa extension support
  2026-03-16  8:28       ` Max Chou
@ 2026-03-19  3:45         ` Alistair Francis
  2026-03-26  3:42           ` Max Chou
  0 siblings, 1 reply; 28+ messages in thread
From: Alistair Francis @ 2026-03-19  3:45 UTC (permalink / raw)
  To: Max Chou
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On Mon, Mar 16, 2026 at 6:28 PM Max Chou <max.chou@sifive.com> wrote:
>
> On 2026-03-13 11:09, Alistair Francis wrote:
> > The problem here is that there is no version control. If we merge this
> > series and the PR changes then suddenly we are out of sync there is no
> > way to track which version of the draft spec we support.
> >
> > We need clear versions, like we previously have. For example version
> > 0.7 and then 0.8. Draft versions are ok, but we need a stable target
> > to develop against.
> >
> > >
> > > PR #2743 is currently open, meaning ratification is pending but not
> > > yet complete. Under the new workflow, merge into main of
> > > riscv-isa-manual is the signal that ratification is finalized. If you
> > > prefer to wait until that merge happens before applying this patchset,
> > > I completely understand. Alternatively, if you are comfortable
> > > accepting it as ratification-pending, I am happy to address any
> > > remaining technical comments.
> >
> > In this case we will have to wait as there is no stable version of the
> > spec to point to.
> >
> > Alistair
> >
>
> Hi Alistair,
>
> Thank you for your feedback on the version control and stability of the
> Zvfbfa specification. I understand your concern about developing against
> a moving target.
>
> To address the lack of a stable target as you mentioned, I’d like to
> help bridge this gap. Since this patchset was prepared based on the
> Zvfbfa version v0.1 and this version has passed the ARC review, I
> propose we coordinate with the Zvfbfa isa designer to check the
> specific tag/commit ID of the Zvfbfa v0.1.


> If we could create a tag or release for v0.1 (e.g., v0.1/v0.1-draft)
> within the Zvfbfa repository that explicitly marks the current state of
> the Zvfbfa spec, would that provide the necessary versioning baseline
> for you to accept this patchset?

Yes, that's how things previously worked. Basically I think we just
need a tag (that won't be changed) in an official RISC-V repo that we
can point to. That way it's easy to say "this is the exact version we
used to write the QEMU implementation". Then if there is a version 0.2
we can easily see what has changed and update to match.

With the seemingly infinite number of draft extensions we need
something to manage the version and compatibility, and that seems like
the best bet.

Posting the draft PDF spec somewhere immutable would also work. We
just need to be able to point to something that won't change and
represents some sort of "release". So a git commit doesn't seem like
enough, we need a "release" that everyone can converge on.

Alistair

>
> My goal is to ensure QEMU supports a traceable version of the draft spec
> while respecting the current RVIA development process for this ISA
> implementation patchset and the followings in the future.
>
> rnax


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 0/9] Add Zvfbfa extension support
  2026-03-19  3:45         ` Alistair Francis
@ 2026-03-26  3:42           ` Max Chou
  2026-03-26  6:07             ` Chao Liu
  0 siblings, 1 reply; 28+ messages in thread
From: Max Chou @ 2026-03-26  3:42 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel, qemu-riscv, Palmer Dabbelt, Alistair Francis,
	Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Chao Liu

On 2026-03-19 13:45, Alistair Francis wrote:
> Yes, that's how things previously worked. Basically I think we just
> need a tag (that won't be changed) in an official RISC-V repo that we
> can point to. That way it's easy to say "this is the exact version we
> used to write the QEMU implementation". Then if there is a version 0.2
> we can easily see what has changed and update to match.
> 

Hi Alistair,

The official riscv-isa-manual repository has added a new tag for the
frozen Zvfbfa v0.9, as shown below:

https://github.com/riscv/riscv-isa-manual/releases/tag/zvfbfa-0.9

The current v5 implementation fully complies with this frozen
specification.

Since the Zvfbfa is frozen, should I prepare a v6 that removes the “x-“
prefix from the zvfbfa property and updates the specification reference
?

Thanks,
rnax

> With the seemingly infinite number of draft extensions we need
> something to manage the version and compatibility, and that seems like
> the best bet.
> 
> Posting the draft PDF spec somewhere immutable would also work. We
> just need to be able to point to something that won't change and
> represents some sort of "release". So a git commit doesn't seem like
> enough, we need a "release" that everyone can converge on.
> 
> Alistair


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH v5 0/9] Add Zvfbfa extension support
  2026-03-26  3:42           ` Max Chou
@ 2026-03-26  6:07             ` Chao Liu
  0 siblings, 0 replies; 28+ messages in thread
From: Chao Liu @ 2026-03-26  6:07 UTC (permalink / raw)
  To: Max Chou
  Cc: Alistair Francis, qemu-devel, qemu-riscv, Palmer Dabbelt,
	Alistair Francis, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei

On Thu, Mar 26, 2026 at 11:42:58AM +0800, Max Chou wrote:
> On 2026-03-19 13:45, Alistair Francis wrote:
> > Yes, that's how things previously worked. Basically I think we just
> > need a tag (that won't be changed) in an official RISC-V repo that we
> > can point to. That way it's easy to say "this is the exact version we
> > used to write the QEMU implementation". Then if there is a version 0.2
> > we can easily see what has changed and update to match.
> > 
> 
> Hi Alistair,
> 
> The official riscv-isa-manual repository has added a new tag for the
> frozen Zvfbfa v0.9, as shown below:
> 
> https://github.com/riscv/riscv-isa-manual/releases/tag/zvfbfa-0.9
> 
> The current v5 implementation fully complies with this frozen
> specification.
> 
> Since the Zvfbfa is frozen, should I prepare a v6 that removes the “x-“
> prefix from the zvfbfa property and updates the specification reference
> ?
I think we need a v6 series, usually it's fine to implementation
after spec tag is release.

That said, we should defer to Alistair's thoughts on this.

Additionally, my new debug spec series can be sent upstream later
(base on the zvfbfa tb ext_flag patch), once zvfbfa ia all ready
and pulled.

Thanks,
Chao
> 
> Thanks,
> rnax
> 
> > With the seemingly infinite number of draft extensions we need
> > something to manage the version and compatibility, and that seems like
> > the best bet.
> > 
> > Posting the draft PDF spec somewhere immutable would also work. We
> > just need to be able to point to something that won't change and
> > represents some sort of "release". So a git commit doesn't seem like
> > enough, we need a "release" that everyone can converge on.
> > 
> > Alistair


^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2026-03-26  6:08 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-06  7:10 [PATCH v5 0/9] Add Zvfbfa extension support Max Chou
2026-03-06  7:10 ` [PATCH v5 1/9] target/riscv: Add cfg properties for Zvfbfa extensions Max Chou
2026-03-09  4:44   ` Alistair Francis
2026-03-06  7:10 ` [PATCH v5 2/9] target/riscv: Add the Zvfbfa extension implied rule Max Chou
2026-03-09  4:45   ` Alistair Francis
2026-03-06  7:10 ` [PATCH v5 3/9] target/riscv: rvv: Add new VTYPE CSR field - altfmt Max Chou
2026-03-09  4:55   ` Alistair Francis
2026-03-16  9:20   ` Nutty.Liu
2026-03-06  7:10 ` [PATCH v5 4/9] target/riscv: rvv: Introduce reset_ill_vtype to reset illegal vtype CSR Max Chou
2026-03-09  4:55   ` Alistair Francis
2026-03-16  9:22   ` Nutty.Liu
2026-03-06  7:11 ` [PATCH v5 5/9] target/riscv: Use the tb->cs_base as the extend tb flags Max Chou
2026-03-09  5:01   ` Alistair Francis
2026-03-12 11:42     ` Max Chou
2026-03-13  0:59       ` Alistair Francis
2026-03-06  7:11 ` [PATCH v5 6/9] target/riscv: Introduce altfmt into DisasContext Max Chou
2026-03-09  5:02   ` Alistair Francis
2026-03-06  7:11 ` [PATCH v5 7/9] target/riscv: Introduce BF16 canonical NaN for Zvfbfa extension Max Chou
2026-03-09  5:04   ` Alistair Francis
2026-03-06  7:11 ` [PATCH v5 8/9] target/riscv: rvv: Support Zvfbfa vector bf16 operations Max Chou
2026-03-06  7:11 ` [PATCH v5 9/9] target/riscv: Expose Zvfbfa extension as an experimental cpu property Max Chou
2026-03-09  4:51 ` [PATCH v5 0/9] Add Zvfbfa extension support Alistair Francis
2026-03-12 11:16   ` Max Chou
2026-03-13  1:09     ` Alistair Francis
2026-03-16  8:28       ` Max Chou
2026-03-19  3:45         ` Alistair Francis
2026-03-26  3:42           ` Max Chou
2026-03-26  6:07             ` Chao Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox