From d8d107ec85caa7abf9f4dfb701e62569cb83a6e0 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Mon, 18 Mar 2019 16:43:14 -0400 Subject: [PATCH] target/riscv: Convert RV64F insns to decodetree Backports commit 95561ee3b41a536cc373e59da10605e2a8676ee2 from qemu --- qemu/target/riscv/insn32-64.decode | 6 ++ qemu/target/riscv/insn_trans/trans_rvf.inc.c | 68 ++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/qemu/target/riscv/insn32-64.decode b/qemu/target/riscv/insn32-64.decode index 0bee95c9..6319f872 100644 --- a/qemu/target/riscv/insn32-64.decode +++ b/qemu/target/riscv/insn32-64.decode @@ -56,3 +56,9 @@ amomin_d 10000 . . ..... ..... 011 ..... 0101111 @atom_st amomax_d 10100 . . ..... ..... 011 ..... 0101111 @atom_st amominu_d 11000 . . ..... ..... 011 ..... 0101111 @atom_st amomaxu_d 11100 . . ..... ..... 011 ..... 0101111 @atom_st + +# *** RV64F Standard Extension (in addition to RV32F) *** +fcvt_l_s 1100000 00010 ..... ... ..... 1010011 @r2_rm +fcvt_lu_s 1100000 00011 ..... ... ..... 1010011 @r2_rm +fcvt_s_l 1101000 00010 ..... ... ..... 1010011 @r2_rm +fcvt_s_lu 1101000 00011 ..... ... ..... 1010011 @r2_rm diff --git a/qemu/target/riscv/insn_trans/trans_rvf.inc.c b/qemu/target/riscv/insn_trans/trans_rvf.inc.c index 6849a253..06e83c28 100644 --- a/qemu/target/riscv/insn_trans/trans_rvf.inc.c +++ b/qemu/target/riscv/insn_trans/trans_rvf.inc.c @@ -427,3 +427,71 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a) return true; } + +#ifdef TARGET_RISCV64 +static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a) +{ + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + REQUIRE_FPU; + REQUIRE_EXT(ctx, RVF); + + TCGv t0 = tcg_temp_new(tcg_ctx); + gen_set_rm(ctx, a->rm); + gen_helper_fcvt_l_s(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[a->rs1]); + gen_set_gpr(ctx, a->rd, t0); + tcg_temp_free(tcg_ctx, t0); + return true; +} + +static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a) +{ + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + REQUIRE_FPU; + REQUIRE_EXT(ctx, RVF); + + TCGv t0 = tcg_temp_new(tcg_ctx); + gen_set_rm(ctx, a->rm); + gen_helper_fcvt_lu_s(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[a->rs1]); + gen_set_gpr(ctx, a->rd, t0); + tcg_temp_free(tcg_ctx, t0); + return true; +} + +static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a) +{ + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + REQUIRE_FPU; + REQUIRE_EXT(ctx, RVF); + + TCGv t0 = tcg_temp_new(tcg_ctx); + gen_get_gpr(ctx, t0, a->rs1); + + gen_set_rm(ctx, a->rm); + gen_helper_fcvt_s_l(tcg_ctx, tcg_ctx->cpu_fpr_risc[a->rd], tcg_ctx->cpu_env, t0); + + mark_fs_dirty(ctx); + tcg_temp_free(tcg_ctx, t0); + return true; +} + +static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a) +{ + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + REQUIRE_FPU; + REQUIRE_EXT(ctx, RVF); + + TCGv t0 = tcg_temp_new(tcg_ctx); + gen_get_gpr(ctx, t0, a->rs1); + + gen_set_rm(ctx, a->rm); + gen_helper_fcvt_s_lu(tcg_ctx, tcg_ctx->cpu_fpr_risc[a->rd], tcg_ctx->cpu_env, t0); + + mark_fs_dirty(ctx); + tcg_temp_free(tcg_ctx, t0); + return true; +} +#endif