[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC v2 15/76] target/riscv: rvv-0.9: add fractional LMUL
From: |
frank . chang |
Subject: |
[RFC v2 15/76] target/riscv: rvv-0.9: add fractional LMUL |
Date: |
Wed, 22 Jul 2020 17:15:38 +0800 |
From: Frank Chang <frank.chang@sifive.com>
Introduce the concepts of fractional LMUL, EEW and EMUL for RVV 0.9.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
---
target/riscv/cpu.h | 16 ++++++++++------
target/riscv/insn_trans/trans_rvv.inc.c | 17 ++++++++++++++---
target/riscv/internals.h | 11 +++++++++--
target/riscv/translate.c | 4 ++++
target/riscv/vector_helper.c | 10 ++++++++--
5 files changed, 45 insertions(+), 13 deletions(-)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0a175151da..a16c6ed8e6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -96,8 +96,9 @@ typedef struct CPURISCVState CPURISCVState;
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, VFLMUL, 5, 1)
+FIELD(VTYPE, VEDIV, 8, 9)
+FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
struct CPURISCVState {
@@ -368,9 +369,10 @@ 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)
+FIELD(TB_FLAGS, LMUL, 3, 3)
+FIELD(TB_FLAGS, SEW, 6, 3)
+/* Skip MSTATUS_VS (0x600) fields */
+FIELD(TB_FLAGS, VILL, 11, 1)
/*
* A simplification for VLMAX
@@ -399,12 +401,14 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState
*env, target_ulong *pc,
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));
+ (FIELD_EX64(env->vtype, VTYPE, VFLMUL) << 2)
+ | 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);
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c
b/target/riscv/insn_trans/trans_rvv.inc.c
index 018a134599..f6f0954c60 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -249,6 +249,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a,
uint8_t seq)
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+ data = FIELD_DP32(data, VDATA, SEW, s->sew);
data = FIELD_DP32(data, VDATA, NF, a->nf);
return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
}
@@ -301,6 +302,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a,
uint8_t seq)
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+ data = FIELD_DP32(data, VDATA, SEW, s->sew);
data = FIELD_DP32(data, VDATA, NF, a->nf);
return ldst_us_trans(a->rd, a->rs1, data, fn, s, true);
}
@@ -387,6 +389,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a,
uint8_t seq)
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+ data = FIELD_DP32(data, VDATA, SEW, s->sew);
data = FIELD_DP32(data, VDATA, NF, a->nf);
return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
}
@@ -425,6 +428,7 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a,
uint8_t seq)
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+ data = FIELD_DP32(data, VDATA, SEW, s->sew);
data = FIELD_DP32(data, VDATA, NF, a->nf);
fn = fns[seq][s->sew];
if (fn == NULL) {
@@ -516,6 +520,7 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a,
uint8_t seq)
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+ data = FIELD_DP32(data, VDATA, SEW, s->sew);
data = FIELD_DP32(data, VDATA, NF, a->nf);
return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
}
@@ -559,6 +564,7 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a,
uint8_t seq)
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+ data = FIELD_DP32(data, VDATA, SEW, s->sew);
data = FIELD_DP32(data, VDATA, NF, a->nf);
return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, true);
}
@@ -637,6 +643,7 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t
seq)
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+ data = FIELD_DP32(data, VDATA, SEW, s->sew);
data = FIELD_DP32(data, VDATA, NF, a->nf);
return ldff_trans(a->rd, a->rs1, data, fn, s);
}
@@ -746,6 +753,7 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t
seq)
data = FIELD_DP32(data, VDATA, VM, a->vm);
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+ data = FIELD_DP32(data, VDATA, SEW, s->sew);
data = FIELD_DP32(data, VDATA, WD, a->wd);
return amo_trans(a->rd, a->rs1, a->rs2, data, fn, s);
}
@@ -1644,7 +1652,8 @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
vreg_ofs(s, a->rs1),
MAXSZ(s), MAXSZ(s));
} else {
- uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+ uint32_t data = 0;
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
static gen_helper_gvec_2_ptr * const fns[4] = {
gen_helper_vmv_v_v_b, gen_helper_vmv_v_v_h,
gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
@@ -1682,7 +1691,8 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
TCGv_i32 desc ;
TCGv_i64 s1_i64 = tcg_temp_new_i64();
TCGv_ptr dest = tcg_temp_new_ptr();
- uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+ uint32_t data = 0;
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
static gen_helper_vmv_vx * const fns[4] = {
gen_helper_vmv_v_x_b, gen_helper_vmv_v_x_h,
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
@@ -1720,7 +1730,8 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
TCGv_i32 desc;
TCGv_i64 s1;
TCGv_ptr dest;
- uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+ uint32_t data = 0;
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
static gen_helper_vmv_vx * const fns[4] = {
gen_helper_vmv_v_x_b, gen_helper_vmv_v_x_h,
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 89fc0753bc..eaf792db5b 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -24,8 +24,9 @@
/* share data between vector helpers and decode code */
FIELD(VDATA, VM, 0, 1)
FIELD(VDATA, LMUL, 1, 3)
-FIELD(VDATA, NF, 4, 4)
-FIELD(VDATA, WD, 4, 1)
+FIELD(VDATA, SEW, 4, 3)
+FIELD(VDATA, NF, 7, 4)
+FIELD(VDATA, WD, 7, 1)
/* float point classify helpers */
target_ulong fclass_h(uint64_t frs1);
@@ -37,4 +38,10 @@ target_ulong fclass_d(uint64_t frs1);
#define SEW32 2
#define SEW64 3
+/* table to convert fractional LMUL value */
+static const float flmul_table[8] = {
+ 1, 2, 4, 8, /* LMUL */
+ -1, /* reserved */
+ 0.125, 0.25, 0.5 /* fractional LMUL */
+};
#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 7593b41a1f..72eb7c2e74 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -60,6 +60,9 @@ typedef struct DisasContext {
/* vector extension */
bool vill;
uint8_t lmul;
+ float flmul;
+ uint8_t eew;
+ float emul;
uint8_t sew;
uint16_t vlen;
bool vl_eq_vlmax;
@@ -823,6 +826,7 @@ static void riscv_tr_init_disas_context(DisasContextBase
*dcbase, CPUState *cs)
ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
ctx->lmul = FIELD_EX32(tb_flags, TB_FLAGS, LMUL);
+ ctx->flmul = flmul_table[ctx->lmul];
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
}
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 6545f91732..a7963c3a2b 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -86,9 +86,15 @@ static inline uint32_t vext_vm(uint32_t desc)
return FIELD_EX32(simd_data(desc), VDATA, VM);
}
-static inline uint32_t vext_lmul(uint32_t desc)
+static inline uint32_t vext_sew(uint32_t desc)
{
- return FIELD_EX32(simd_data(desc), VDATA, LMUL);
+ return 1 << (FIELD_EX32(simd_data(desc), VDATA, SEW) + 3);
+}
+
+static inline float vext_vflmul(uint32_t desc)
+{
+ uint32_t lmul = FIELD_EX32(simd_data(desc), VDATA, LMUL);
+ return flmul_table[lmul];
}
static uint32_t vext_wd(uint32_t desc)
--
2.17.1
- [RFC v2 10/76] target/riscv: rvv-0.9: add translation-time vector context status, (continued)
- [RFC v2 10/76] target/riscv: rvv-0.9: add translation-time vector context status, frank . chang, 2020/07/22
- [RFC v2 11/76] target/riscv: rvv-0.9: remove vxrm and vxsat fields from fcsr register, frank . chang, 2020/07/22
- [RFC v2 12/76] target/riscv: rvv-0.9: add vcsr register, frank . chang, 2020/07/22
- [RFC v2 13/76] target/riscv: rvv-0.9: add vlenb register, frank . chang, 2020/07/22
- [RFC v2 14/76] target/riscv: rvv-0.9: remove MLEN calculations, frank . chang, 2020/07/22
- [RFC v2 15/76] target/riscv: rvv-0.9: add fractional LMUL,
frank . chang <=
- [RFC v2 16/76] target/riscv: rvv-0.9: add VMA and VTA, frank . chang, 2020/07/22
- [RFC v2 17/76] target/riscv: rvv-0.9: update check functions, frank . chang, 2020/07/22
- [RFC v2 18/76] target/riscv: introduce more imm value modes in translator functions, frank . chang, 2020/07/22
- [RFC v2 19/76] target/riscv: rvv-0.9: add narrower_nanbox_fpr helper, frank . chang, 2020/07/22