123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- From 371b8815c98cf4e3f8e2048c3b2ee1c2830e537f Mon Sep 17 00:00:00 2001
- From: Frank Chang <frank.chang@sifive.com>
- Date: Thu, 30 Jul 2020 18:40:37 +0800
- Subject: [PATCH 025/107] target/riscv: rvv-1.0: configure instructions
- 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>
- ---
- target/riscv/insn_trans/trans_rvv.c.inc | 53 +++++++++----------------
- target/riscv/vector_helper.c | 14 ++++++-
- 2 files changed, 31 insertions(+), 36 deletions(-)
- diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
- index dcffc14909..fcb01d1b5f 100644
- --- a/target/riscv/insn_trans/trans_rvv.c.inc
- +++ b/target/riscv/insn_trans/trans_rvv.c.inc
- @@ -132,28 +132,29 @@ static bool require_noover_seg(const int8_t dst, const int8_t nf,
- return !is_overlapped(dst, nf, src, 1);
- }
-
- -static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
- +static bool do_vsetvl(DisasContext *ctx, int rd, int rs1, TCGv s2)
- {
- - TCGv s1, s2, dst;
- + TCGv s1, dst;
-
- if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
- return false;
- }
-
- - s2 = tcg_temp_new();
- dst = tcg_temp_new();
-
- - /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
- - if (a->rs1 == 0) {
- + if (rd == 0 && rs1 == 0) {
- + s1 = tcg_temp_new();
- + tcg_gen_mov_tl(s1, cpu_vl);
- + } else if (rs1 == 0) {
- /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
- s1 = tcg_const_tl(RV_VLEN_MAX);
- } else {
- s1 = tcg_temp_new();
- - gen_get_gpr(s1, a->rs1);
- + gen_get_gpr(s1, rs1);
- }
- - gen_get_gpr(s2, a->rs2);
- +
- gen_helper_vsetvl(dst, cpu_env, s1, s2);
- - gen_set_gpr(a->rd, dst);
- + gen_set_gpr(rd, dst);
- mark_vs_dirty(ctx);
- tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
- lookup_and_goto_ptr(ctx);
- @@ -165,35 +166,17 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
- return true;
- }
-
- -static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
- +static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
- {
- - TCGv s1, s2, dst;
- -
- - if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
- - return false;
- - }
- -
- - s2 = tcg_const_tl(a->zimm);
- - dst = tcg_temp_new();
- -
- - /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
- - if (a->rs1 == 0) {
- - /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
- - s1 = tcg_const_tl(RV_VLEN_MAX);
- - } else {
- - s1 = tcg_temp_new();
- - gen_get_gpr(s1, a->rs1);
- - }
- - gen_helper_vsetvl(dst, cpu_env, s1, s2);
- - gen_set_gpr(a->rd, dst);
- - mark_vs_dirty(ctx);
- - gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
- - ctx->base.is_jmp = DISAS_NORETURN;
- + TCGv s2 = tcg_temp_new();
- + gen_get_gpr(s2, a->rs2);
- + return do_vsetvl(ctx, a->rd, a->rs1, s2);
- +}
-
- - tcg_temp_free(s1);
- - tcg_temp_free(s2);
- - tcg_temp_free(dst);
- - return true;
- +static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
- +{
- + TCGv s2 = tcg_const_tl(a->zimm);
- + return do_vsetvl(ctx, a->rd, a->rs1, s2);
- }
-
- /* vector register offset from env */
- diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
- index 5a142a1f4b..e8912ee8fe 100644
- --- a/target/riscv/vector_helper.c
- +++ b/target/riscv/vector_helper.c
- @@ -31,12 +31,24 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
- {
- int vlmax, vl;
- RISCVCPU *cpu = env_archcpu(env);
- + uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
- uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
- uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
- bool vill = FIELD_EX64(s2, VTYPE, VILL);
- target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED);
-
- - if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
- + if (lmul & 4) {
- + /* Fractional LMUL. */
- + if (lmul == 4 ||
- + cpu->cfg.elen >> (8 - lmul) < sew) {
- + vill = true;
- + }
- + }
- +
- + if ((sew > cpu->cfg.elen)
- + || vill
- + || (ediv != 0)
- + || (reserved != 0)) {
- /* only set vill bit. */
- env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
- env->vl = 0;
- --
- 2.33.1
|