mirror of
https://github.com/qemu/qemu.git
synced 2024-12-05 09:43:44 +08:00
target/riscv: rvv-1.0: take fractional LMUL into vector max elements calculation
Update vext_get_vlmax() and MAXSZ() to take fractional LMUL into calculation for RVV 1.0. 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> Message-Id: <20211210075704.23951-27-frank.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
5a9f8e1552
commit
a689a82b7f
@ -430,18 +430,27 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A simplification for VLMAX
|
* Encode LMUL to lmul as follows:
|
||||||
* = (1 << LMUL) * VLEN / (8 * (1 << SEW))
|
* LMUL vlmul lmul
|
||||||
* = (VLEN << LMUL) / (8 << SEW)
|
* 1 000 0
|
||||||
* = (VLEN << LMUL) >> (SEW + 3)
|
* 2 001 1
|
||||||
* = VLEN >> (SEW + 3 - LMUL)
|
* 4 010 2
|
||||||
|
* 8 011 3
|
||||||
|
* - 100 -
|
||||||
|
* 1/8 101 -3
|
||||||
|
* 1/4 110 -2
|
||||||
|
* 1/2 111 -1
|
||||||
|
*
|
||||||
|
* then, we can calculate VLMAX = vlen >> (vsew + 3 - lmul)
|
||||||
|
* e.g. vlen = 256 bits, SEW = 16, LMUL = 1/8
|
||||||
|
* => VLMAX = vlen >> (1 + 3 - (-3))
|
||||||
|
* = 256 >> 7
|
||||||
|
* = 2
|
||||||
*/
|
*/
|
||||||
static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
|
static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
|
||||||
{
|
{
|
||||||
uint8_t sew, lmul;
|
uint8_t sew = FIELD_EX64(vtype, VTYPE, VSEW);
|
||||||
|
int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
|
||||||
sew = FIELD_EX64(vtype, VTYPE, VSEW);
|
|
||||||
lmul = FIELD_EX64(vtype, VTYPE, VLMUL);
|
|
||||||
return cpu->cfg.vlen >> (sew + 3 - lmul);
|
return cpu->cfg.vlen >> (sew + 3 - lmul);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,12 +75,22 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
|
|||||||
*cs_base = 0;
|
*cs_base = 0;
|
||||||
|
|
||||||
if (riscv_has_ext(env, RVV)) {
|
if (riscv_has_ext(env, RVV)) {
|
||||||
|
/*
|
||||||
|
* If env->vl equals to VLMAX, we can use generic vector operation
|
||||||
|
* expanders (GVEC) to accerlate the vector operations.
|
||||||
|
* However, as LMUL could be a fractional number. The maximum
|
||||||
|
* vector size can be operated might be less than 8 bytes,
|
||||||
|
* which is not supported by GVEC. So we set vl_eq_vlmax flag to true
|
||||||
|
* only when maxsz >= 8 bytes.
|
||||||
|
*/
|
||||||
uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
|
uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
|
||||||
bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
|
uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
|
||||||
|
uint32_t maxsz = vlmax << sew;
|
||||||
|
bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
|
||||||
|
(maxsz >= 8);
|
||||||
flags = FIELD_DP32(flags, TB_FLAGS, VILL,
|
flags = FIELD_DP32(flags, TB_FLAGS, VILL,
|
||||||
FIELD_EX64(env->vtype, VTYPE, VILL));
|
FIELD_EX64(env->vtype, VTYPE, VILL));
|
||||||
flags = FIELD_DP32(flags, TB_FLAGS, SEW,
|
flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
|
||||||
FIELD_EX64(env->vtype, VTYPE, VSEW));
|
|
||||||
flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
|
flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
|
||||||
FIELD_EX64(env->vtype, VTYPE, VLMUL));
|
FIELD_EX64(env->vtype, VTYPE, VLMUL));
|
||||||
flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
|
flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
|
||||||
|
@ -1049,7 +1049,17 @@ GEN_LDST_WHOLE_TRANS(vs8r_v, 8, true)
|
|||||||
/*
|
/*
|
||||||
*** Vector Integer Arithmetic Instructions
|
*** Vector Integer Arithmetic Instructions
|
||||||
*/
|
*/
|
||||||
#define MAXSZ(s) (s->vlen >> (3 - s->lmul))
|
|
||||||
|
/*
|
||||||
|
* MAXSZ returns the maximum vector size can be operated in bytes,
|
||||||
|
* which is used in GVEC IR when vl_eq_vlmax flag is set to true
|
||||||
|
* to accerlate vector operation.
|
||||||
|
*/
|
||||||
|
static inline uint32_t MAXSZ(DisasContext *s)
|
||||||
|
{
|
||||||
|
int scale = s->lmul - 3;
|
||||||
|
return scale < 0 ? s->vlen >> -scale : s->vlen << scale;
|
||||||
|
}
|
||||||
|
|
||||||
static bool opivv_check(DisasContext *s, arg_rmrr *a)
|
static bool opivv_check(DisasContext *s, arg_rmrr *a)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user