From: Frank Chang <frank.chang@sifive.com>
Zfhmin extension is a subset of Zfh extension, consisting only of data
transfer and conversion instructions.
If enabled, only the following instructions from Zfh extension are
included:
* flh, fsh, fmv.x.h, fmv.h.x, fcvt.s.h, fcvt.h.s
* If D extension is present: fcvt.d.h, fcvt.h.d
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
target/riscv/cpu.c | 1 +
target/riscv/cpu.h | 1 +
target/riscv/insn_trans/trans_rvzfh.c.inc | 22 ++++++++++++++--------
target/riscv/translate.c | 2 ++
4 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 8c579dc297b..4c0e6532164 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -602,6 +602,7 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
+ DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 88684e72be1..d70f63ddfe6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -298,6 +298,7 @@ struct RISCVCPU {
bool ext_ifencei;
bool ext_icsr;
bool ext_zfh;
+ bool ext_zfhmin;
char *priv_spec;
char *user_spec;
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc
index 0549e25fb45..5a7cac89585 100644
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -22,13 +22,19 @@
} \
} while (0)
+#define REQUIRE_ZFH_OR_ZFHMIN(ctx) do { \
+ if (!(ctx->ext_zfh || ctx->ext_zfhmin)) { \
+ return false; \
+ } \
+} while (0)
+
static bool trans_flh(DisasContext *ctx, arg_flh *a)
{
TCGv_i64 dest;
TCGv t0;
REQUIRE_FPU;
- REQUIRE_ZFH(ctx);
+ REQUIRE_ZFH_OR_ZFHMIN(ctx);
t0 = get_gpr(ctx, a->rs1, EXT_NONE);
if (a->imm) {
@@ -50,7 +56,7 @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
TCGv t0;
REQUIRE_FPU;
- REQUIRE_ZFH(ctx);
+ REQUIRE_ZFH_OR_ZFHMIN(ctx);
t0 = get_gpr(ctx, a->rs1, EXT_NONE);
if (a->imm) {
@@ -283,7 +289,7 @@ static bool trans_fmax_h(DisasContext *ctx, arg_fmax_h *a)
static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a)
{
REQUIRE_FPU;
- REQUIRE_ZFH(ctx);
+ REQUIRE_ZFH_OR_ZFHMIN(ctx);
gen_set_rm(ctx, a->rm);
gen_helper_fcvt_s_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
@@ -296,7 +302,7 @@ static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a)
static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a)
{
REQUIRE_FPU;
- REQUIRE_ZFH(ctx);
+ REQUIRE_ZFH_OR_ZFHMIN(ctx);
REQUIRE_EXT(ctx, RVD);
gen_set_rm(ctx, a->rm);
@@ -311,7 +317,7 @@ static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a)
static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a)
{
REQUIRE_FPU;
- REQUIRE_ZFH(ctx);
+ REQUIRE_ZFH_OR_ZFHMIN(ctx);
gen_set_rm(ctx, a->rm);
gen_helper_fcvt_h_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
@@ -324,7 +330,7 @@ static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a)
static bool trans_fcvt_h_d(DisasContext *ctx, arg_fcvt_h_d *a)
{
REQUIRE_FPU;
- REQUIRE_ZFH(ctx);
+ REQUIRE_ZFH_OR_ZFHMIN(ctx);
REQUIRE_EXT(ctx, RVD);
gen_set_rm(ctx, a->rm);
@@ -441,7 +447,7 @@ static bool trans_fcvt_h_wu(DisasContext *ctx, arg_fcvt_h_wu *a)
static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
{
REQUIRE_FPU;
- REQUIRE_ZFH(ctx);
+ REQUIRE_ZFH_OR_ZFHMIN(ctx);
TCGv dest = dest_gpr(ctx, a->rd);
@@ -461,7 +467,7 @@ static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
static bool trans_fmv_h_x(DisasContext *ctx, arg_fmv_h_x *a)
{
REQUIRE_FPU;
- REQUIRE_ZFH(ctx);
+ REQUIRE_ZFH_OR_ZFHMIN(ctx);
TCGv t0 = get_gpr(ctx, a->rs1, EXT_ZERO);
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 442ef42f441..f23bc919c08 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -70,6 +70,7 @@ typedef struct DisasContext {
bool virt_enabled;
bool ext_ifencei;
bool ext_zfh;
+ bool ext_zfhmin;
bool hlsx;
/* vector extension */
bool vill;
@@ -559,6 +560,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
ctx->frm = -1; /* unknown rounding mode */
ctx->ext_ifencei = cpu->cfg.ext_ifencei;
ctx->ext_zfh = cpu->cfg.ext_zfh;
+ ctx->ext_zfhmin = cpu->cfg.ext_zfhmin;
ctx->vlen = cpu->cfg.vlen;
ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS);
ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX);
--
2.25.1
On Sat, Oct 16, 2021 at 7:13 PM <frank.chang@sifive.com> wrote:
>
> From: Frank Chang <frank.chang@sifive.com>
>
> Zfhmin extension is a subset of Zfh extension, consisting only of data
> transfer and conversion instructions.
>
> If enabled, only the following instructions from Zfh extension are
> included:
> * flh, fsh, fmv.x.h, fmv.h.x, fcvt.s.h, fcvt.h.s
> * If D extension is present: fcvt.d.h, fcvt.h.d
>
> Signed-off-by: Frank Chang <frank.chang@sifive.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/cpu.c | 1 +
> target/riscv/cpu.h | 1 +
> target/riscv/insn_trans/trans_rvzfh.c.inc | 22 ++++++++++++++--------
> target/riscv/translate.c | 2 ++
> 4 files changed, 18 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 8c579dc297b..4c0e6532164 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -602,6 +602,7 @@ static Property riscv_cpu_properties[] = {
> DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
> + DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
> DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
> DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
> DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 88684e72be1..d70f63ddfe6 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -298,6 +298,7 @@ struct RISCVCPU {
> bool ext_ifencei;
> bool ext_icsr;
> bool ext_zfh;
> + bool ext_zfhmin;
>
> char *priv_spec;
> char *user_spec;
> diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc
> index 0549e25fb45..5a7cac89585 100644
> --- a/target/riscv/insn_trans/trans_rvzfh.c.inc
> +++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
> @@ -22,13 +22,19 @@
> } \
> } while (0)
>
> +#define REQUIRE_ZFH_OR_ZFHMIN(ctx) do { \
> + if (!(ctx->ext_zfh || ctx->ext_zfhmin)) { \
> + return false; \
> + } \
> +} while (0)
> +
> static bool trans_flh(DisasContext *ctx, arg_flh *a)
> {
> TCGv_i64 dest;
> TCGv t0;
>
> REQUIRE_FPU;
> - REQUIRE_ZFH(ctx);
> + REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
> t0 = get_gpr(ctx, a->rs1, EXT_NONE);
> if (a->imm) {
> @@ -50,7 +56,7 @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
> TCGv t0;
>
> REQUIRE_FPU;
> - REQUIRE_ZFH(ctx);
> + REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
> t0 = get_gpr(ctx, a->rs1, EXT_NONE);
> if (a->imm) {
> @@ -283,7 +289,7 @@ static bool trans_fmax_h(DisasContext *ctx, arg_fmax_h *a)
> static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a)
> {
> REQUIRE_FPU;
> - REQUIRE_ZFH(ctx);
> + REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
> gen_set_rm(ctx, a->rm);
> gen_helper_fcvt_s_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
> @@ -296,7 +302,7 @@ static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a)
> static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a)
> {
> REQUIRE_FPU;
> - REQUIRE_ZFH(ctx);
> + REQUIRE_ZFH_OR_ZFHMIN(ctx);
> REQUIRE_EXT(ctx, RVD);
>
> gen_set_rm(ctx, a->rm);
> @@ -311,7 +317,7 @@ static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a)
> static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a)
> {
> REQUIRE_FPU;
> - REQUIRE_ZFH(ctx);
> + REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
> gen_set_rm(ctx, a->rm);
> gen_helper_fcvt_h_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
> @@ -324,7 +330,7 @@ static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a)
> static bool trans_fcvt_h_d(DisasContext *ctx, arg_fcvt_h_d *a)
> {
> REQUIRE_FPU;
> - REQUIRE_ZFH(ctx);
> + REQUIRE_ZFH_OR_ZFHMIN(ctx);
> REQUIRE_EXT(ctx, RVD);
>
> gen_set_rm(ctx, a->rm);
> @@ -441,7 +447,7 @@ static bool trans_fcvt_h_wu(DisasContext *ctx, arg_fcvt_h_wu *a)
> static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
> {
> REQUIRE_FPU;
> - REQUIRE_ZFH(ctx);
> + REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
> TCGv dest = dest_gpr(ctx, a->rd);
>
> @@ -461,7 +467,7 @@ static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
> static bool trans_fmv_h_x(DisasContext *ctx, arg_fmv_h_x *a)
> {
> REQUIRE_FPU;
> - REQUIRE_ZFH(ctx);
> + REQUIRE_ZFH_OR_ZFHMIN(ctx);
>
> TCGv t0 = get_gpr(ctx, a->rs1, EXT_ZERO);
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 442ef42f441..f23bc919c08 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -70,6 +70,7 @@ typedef struct DisasContext {
> bool virt_enabled;
> bool ext_ifencei;
> bool ext_zfh;
> + bool ext_zfhmin;
> bool hlsx;
> /* vector extension */
> bool vill;
> @@ -559,6 +560,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
> ctx->frm = -1; /* unknown rounding mode */
> ctx->ext_ifencei = cpu->cfg.ext_ifencei;
> ctx->ext_zfh = cpu->cfg.ext_zfh;
> + ctx->ext_zfhmin = cpu->cfg.ext_zfhmin;
> ctx->vlen = cpu->cfg.vlen;
> ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS);
> ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX);
> --
> 2.25.1
>
>
© 2016 - 2026 Red Hat, Inc.