According to the Zvfofp8min extension, the vfncvtbf16.f.f.w instruction
supports BF16 to OFP8 conversion without satuation when SEW is 8.
And the VTYPE.altfmt field is used to select the OFP8 format.
* altfmt = 0: BF16 to OFP8.e4m3
* altfmt = 1: BF16 to OFP8.e5m2
Signed-off-by: Max Chou <max.chou@sifive.com>
---
target/riscv/insn_trans/trans_rvbf16.c.inc | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc b/target/riscv/insn_trans/trans_rvbf16.c.inc
index 9aafd4d2ef..16f4403909 100644
--- a/target/riscv/insn_trans/trans_rvbf16.c.inc
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
@@ -67,11 +67,20 @@ static bool trans_fcvt_s_bf16(DisasContext *ctx, arg_fcvt_s_bf16 *a)
static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
{
REQUIRE_FPU;
- REQUIRE_ZVFBFMIN(ctx);
- if (opfv_narrow_check(ctx, a) && (ctx->sew == MO_16)) {
+ if (opfv_narrow_check(ctx, a) &&
+ ((ctx->sew == MO_16 && ctx->cfg_ptr->ext_zvfbfmin) ||
+ (ctx->sew == MO_8 && ctx->cfg_ptr->ext_zvfofp8min))) {
+ gen_helper_gvec_3_ptr *fn;
uint32_t data = 0;
+ if (ctx->sew == MO_16) {
+ fn = gen_helper_vfncvtbf16_f_f_w;
+ } else {
+ fn = ctx->altfmt ? gen_helper_vfncvtbf16_f_f_w_ofp8e5m2 :
+ gen_helper_vfncvtbf16_f_f_w_ofp8e4m3;
+ }
+
gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
data = FIELD_DP32(data, VDATA, VM, a->vm);
@@ -81,8 +90,7 @@ static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
tcg_gen_gvec_3_ptr(vreg_ofs(ctx, a->rd), vreg_ofs(ctx, 0),
vreg_ofs(ctx, a->rs2), tcg_env,
ctx->cfg_ptr->vlenb,
- ctx->cfg_ptr->vlenb, data,
- gen_helper_vfncvtbf16_f_f_w);
+ ctx->cfg_ptr->vlenb, data, fn);
finalize_rvv_inst(ctx);
return true;
}
--
2.52.0