diff options
author | Weiwei Li <liweiwei@iscas.ac.cn> | 2022-02-11 12:39:17 +0800 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2022-03-03 13:14:50 +1000 |
commit | e1a29bbd5493634afd52f1724331728abdd196b8 (patch) | |
tree | 0025d737c28ca6e1100554d8f06869ff73d6d4f8 /target/riscv/translate.c | |
parent | c163b3baf93cdccc531410f76598cc8146b8f578 (diff) |
target/riscv: add support for zfinx
- update extension check REQUIRE_ZFINX_OR_F
- update single float point register read/write
- disable nanbox_s check
Co-authored-by: ardxwe <ardxwe@gmail.com>
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20220211043920.28981-4-liweiwei@iscas.ac.cn>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv/translate.c')
-rw-r--r-- | target/riscv/translate.c | 93 |
1 files changed, 92 insertions, 1 deletions
diff --git a/target/riscv/translate.c b/target/riscv/translate.c index c7232de326..10cf37be41 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -101,6 +101,9 @@ typedef struct DisasContext { TCGv zero; /* Space for 3 operands plus 1 extra for address computation. */ TCGv temp[4]; + /* Space for 4 operands(1 dest and <=3 src) for float point computation */ + TCGv_i64 ftemp[4]; + uint8_t nftemp; /* PointerMasking extension */ bool pm_mask_enabled; bool pm_base_enabled; @@ -380,6 +383,86 @@ static void gen_set_gpr128(DisasContext *ctx, int reg_num, TCGv rl, TCGv rh) } } +static TCGv_i64 ftemp_new(DisasContext *ctx) +{ + assert(ctx->nftemp < ARRAY_SIZE(ctx->ftemp)); + return ctx->ftemp[ctx->nftemp++] = tcg_temp_new_i64(); +} + +static TCGv_i64 get_fpr_hs(DisasContext *ctx, int reg_num) +{ + if (!ctx->cfg_ptr->ext_zfinx) { + return cpu_fpr[reg_num]; + } + + if (reg_num == 0) { + return tcg_constant_i64(0); + } + switch (get_xl(ctx)) { + case MXL_RV32: +#ifdef TARGET_RISCV32 + { + TCGv_i64 t = ftemp_new(ctx); + tcg_gen_ext_i32_i64(t, cpu_gpr[reg_num]); + return t; + } +#else + /* fall through */ + case MXL_RV64: + return cpu_gpr[reg_num]; +#endif + default: + g_assert_not_reached(); + } +} + +static TCGv_i64 dest_fpr(DisasContext *ctx, int reg_num) +{ + if (!ctx->cfg_ptr->ext_zfinx) { + return cpu_fpr[reg_num]; + } + + if (reg_num == 0) { + return ftemp_new(ctx); + } + + switch (get_xl(ctx)) { + case MXL_RV32: + return ftemp_new(ctx); +#ifdef TARGET_RISCV64 + case MXL_RV64: + return cpu_gpr[reg_num]; +#endif + default: + g_assert_not_reached(); + } +} + +/* assume t is nanboxing (for normal) or sign-extended (for zfinx) */ +static void gen_set_fpr_hs(DisasContext *ctx, int reg_num, TCGv_i64 t) +{ + if (!ctx->cfg_ptr->ext_zfinx) { + tcg_gen_mov_i64(cpu_fpr[reg_num], t); + return; + } + if (reg_num != 0) { + switch (get_xl(ctx)) { + case MXL_RV32: +#ifdef TARGET_RISCV32 + tcg_gen_extrl_i64_i32(cpu_gpr[reg_num], t); + break; +#else + /* fall through */ + case MXL_RV64: + tcg_gen_mov_i64(cpu_gpr[reg_num], t); + break; +#endif + default: + g_assert_not_reached(); + } + } +} + static void gen_jal(DisasContext *ctx, int rd, target_ulong imm) { target_ulong next_pc; @@ -955,6 +1038,8 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->cs = cs; ctx->ntemp = 0; memset(ctx->temp, 0, sizeof(ctx->temp)); + ctx->nftemp = 0; + memset(ctx->ftemp, 0, sizeof(ctx->ftemp)); ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED); ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED); ctx->zero = tcg_constant_tl(0); @@ -976,16 +1061,22 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) DisasContext *ctx = container_of(dcbase, DisasContext, base); CPURISCVState *env = cpu->env_ptr; uint16_t opcode16 = translator_lduw(env, &ctx->base, ctx->base.pc_next); + int i; ctx->ol = ctx->xl; decode_opc(env, ctx, opcode16); ctx->base.pc_next = ctx->pc_succ_insn; - for (int i = ctx->ntemp - 1; i >= 0; --i) { + for (i = ctx->ntemp - 1; i >= 0; --i) { tcg_temp_free(ctx->temp[i]); ctx->temp[i] = NULL; } ctx->ntemp = 0; + for (i = ctx->nftemp - 1; i >= 0; --i) { + tcg_temp_free_i64(ctx->ftemp[i]); + ctx->ftemp[i] = NULL; + } + ctx->nftemp = 0; if (ctx->base.is_jmp == DISAS_NEXT) { target_ulong page_start; |