diff options
author | LIU Zhiwei <zhiwei_liu@c-sky.com> | 2020-07-01 23:24:52 +0800 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2020-07-02 09:19:32 -0700 |
commit | 2b7168fc43fb270fb89e1dddc17ef54714712f3a (patch) | |
tree | 16f1ef7e07de0c8454d93c3cd28536a8d92247f0 /target/riscv/cpu.h | |
parent | 8e3a1f18871e0ea251b95561fe1ec5a9bc896c4a (diff) |
target/riscv: add vector configure instruction
vsetvl and vsetvli are two configure instructions for vl, vtype. TB flags
should update after configure instructions. The (ill, lmul, sew ) of vtype
and the bit of (VSTART == 0 && VL == VLMAX) will be placed within tb_flags.
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20200701152549.1218-5-zhiwei_liu@c-sky.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv/cpu.h')
-rw-r--r-- | target/riscv/cpu.h | 63 |
1 files changed, 54 insertions, 9 deletions
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 302e0859a0..0ad51c6580 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -21,6 +21,7 @@ #define RISCV_CPU_H #include "hw/core/cpu.h" +#include "hw/registerfields.h" #include "exec/cpu-defs.h" #include "fpu/softfloat-types.h" @@ -93,6 +94,12 @@ typedef struct CPURISCVState CPURISCVState; #define RV_VLEN_MAX 512 +FIELD(VTYPE, VLMUL, 0, 2) +FIELD(VTYPE, VSEW, 2, 3) +FIELD(VTYPE, VEDIV, 5, 2) +FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9) +FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 2, 1) + struct CPURISCVState { target_ulong gpr[32]; uint64_t fpr[32]; /* assume both F and D extensions */ @@ -352,19 +359,62 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong); #define TB_FLAGS_MMU_MASK 3 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS +typedef CPURISCVState CPUArchState; +typedef RISCVCPU ArchCPU; +#include "exec/cpu-all.h" + +FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1) +FIELD(TB_FLAGS, LMUL, 3, 2) +FIELD(TB_FLAGS, SEW, 5, 3) +FIELD(TB_FLAGS, VILL, 8, 1) + +/* + * A simplification for VLMAX + * = (1 << LMUL) * VLEN / (8 * (1 << SEW)) + * = (VLEN << LMUL) / (8 << SEW) + * = (VLEN << LMUL) >> (SEW + 3) + * = VLEN >> (SEW + 3 - LMUL) + */ +static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype) +{ + uint8_t sew, lmul; + + sew = FIELD_EX64(vtype, VTYPE, VSEW); + lmul = FIELD_EX64(vtype, VTYPE, VLMUL); + return cpu->cfg.vlen >> (sew + 3 - lmul); +} + static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, - target_ulong *cs_base, uint32_t *flags) + target_ulong *cs_base, uint32_t *pflags) { + uint32_t flags = 0; + *pc = env->pc; *cs_base = 0; + + if (riscv_has_ext(env, RVV)) { + uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype); + bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl); + flags = FIELD_DP32(flags, TB_FLAGS, VILL, + FIELD_EX64(env->vtype, VTYPE, VILL)); + flags = FIELD_DP32(flags, TB_FLAGS, SEW, + FIELD_EX64(env->vtype, VTYPE, VSEW)); + flags = FIELD_DP32(flags, TB_FLAGS, LMUL, + FIELD_EX64(env->vtype, VTYPE, VLMUL)); + flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax); + } else { + flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1); + } + #ifdef CONFIG_USER_ONLY - *flags = TB_FLAGS_MSTATUS_FS; + flags |= TB_FLAGS_MSTATUS_FS; #else - *flags = cpu_mmu_index(env, 0); + flags |= cpu_mmu_index(env, 0); if (riscv_cpu_fp_enabled(env)) { - *flags |= env->mstatus & MSTATUS_FS; + flags |= env->mstatus & MSTATUS_FS; } #endif + *pflags = flags; } int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value, @@ -405,9 +455,4 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops); void riscv_cpu_register_gdb_regs_for_features(CPUState *cs); -typedef CPURISCVState CPUArchState; -typedef RISCVCPU ArchCPU; - -#include "exec/cpu-all.h" - #endif /* RISCV_CPU_H */ |