123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- From 1c1e08410bf1c6f1f8fe14aaa369b9cb57192293 Mon Sep 17 00:00:00 2001
- From: Frank Chang <frank.chang@sifive.com>
- Date: Tue, 29 Sep 2020 23:25:37 +0800
- Subject: [PATCH 032/107] target/riscv: rvv-1.0: update vext_max_elems() for
- load/store insns
- Signed-off-by: Frank Chang <frank.chang@sifive.com>
- Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
- ---
- target/riscv/insn_trans/trans_rvv.c.inc | 32 +++++++--
- target/riscv/vector_helper.c | 90 ++++++++++++++-----------
- 2 files changed, 74 insertions(+), 48 deletions(-)
- diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
- index 146d330894..a992bd170d 100644
- --- a/target/riscv/insn_trans/trans_rvv.c.inc
- +++ b/target/riscv/insn_trans/trans_rvv.c.inc
- @@ -586,6 +586,12 @@ static bool trans_##NAME(DisasContext *s, arg_##ARGTYPE * a) \
- return false; \
- }
-
- +static uint8_t vext_get_emul(DisasContext *s, uint8_t eew)
- +{
- + int8_t emul = eew - s->sew + s->lmul;
- + return emul < 0 ? 0 : emul;
- +}
- +
- /*
- *** unit stride load and store
- */
- @@ -651,8 +657,14 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew)
- return false;
- }
-
- + /*
- + * Vector load/store instructions have the EEW encoded
- + * directly in the instructions. The maximum vector size is
- + * calculated with EMUL rather than LMUL.
- + */
- + uint8_t emul = vext_get_emul(s, eew);
- data = FIELD_DP32(data, VDATA, VM, a->vm);
- - data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
- + data = FIELD_DP32(data, VDATA, LMUL, emul);
- data = FIELD_DP32(data, VDATA, NF, a->nf);
- return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
- }
- @@ -687,8 +699,9 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew)
- return false;
- }
-
- + uint8_t emul = vext_get_emul(s, eew);
- data = FIELD_DP32(data, VDATA, VM, a->vm);
- - data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
- + data = FIELD_DP32(data, VDATA, LMUL, emul);
- data = FIELD_DP32(data, VDATA, NF, a->nf);
- return ldst_us_trans(a->rd, a->rs1, data, fn, s, true);
- }
- @@ -761,8 +774,9 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t eew)
- return false;
- }
-
- + uint8_t emul = vext_get_emul(s, eew);
- data = FIELD_DP32(data, VDATA, VM, a->vm);
- - data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
- + data = FIELD_DP32(data, VDATA, LMUL, emul);
- data = FIELD_DP32(data, VDATA, NF, a->nf);
- return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
- }
- @@ -789,8 +803,9 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, uint8_t eew)
- gen_helper_vsse32_v, gen_helper_vsse64_v
- };
-
- + uint8_t emul = vext_get_emul(s, eew);
- data = FIELD_DP32(data, VDATA, VM, a->vm);
- - data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
- + data = FIELD_DP32(data, VDATA, LMUL, emul);
- data = FIELD_DP32(data, VDATA, NF, a->nf);
- fn = fns[eew];
- if (fn == NULL) {
- @@ -887,8 +902,9 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, uint8_t eew)
-
- fn = fns[eew][s->sew];
-
- + uint8_t emul = vext_get_emul(s, s->sew);
- data = FIELD_DP32(data, VDATA, VM, a->vm);
- - data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
- + data = FIELD_DP32(data, VDATA, LMUL, emul);
- data = FIELD_DP32(data, VDATA, NF, a->nf);
- return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
- }
- @@ -938,8 +954,9 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, uint8_t eew)
-
- fn = fns[eew][s->sew];
-
- + uint8_t emul = vext_get_emul(s, s->sew);
- data = FIELD_DP32(data, VDATA, VM, a->vm);
- - data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
- + data = FIELD_DP32(data, VDATA, LMUL, emul);
- data = FIELD_DP32(data, VDATA, NF, a->nf);
- return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, true);
- }
- @@ -1003,8 +1020,9 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew)
- return false;
- }
-
- + uint8_t emul = vext_get_emul(s, eew);
- data = FIELD_DP32(data, VDATA, VM, a->vm);
- - data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
- + data = FIELD_DP32(data, VDATA, LMUL, emul);
- data = FIELD_DP32(data, VDATA, NF, a->nf);
- return ldff_trans(a->rd, a->rs1, data, fn, s);
- }
- diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
- index 05ec6e040c..0a9fb898a1 100644
- --- a/target/riscv/vector_helper.c
- +++ b/target/riscv/vector_helper.c
- @@ -17,6 +17,7 @@
- */
-
- #include "qemu/osdep.h"
- +#include "qemu/host-utils.h"
- #include "cpu.h"
- #include "exec/memop.h"
- #include "exec/exec-all.h"
- @@ -121,14 +122,21 @@ static uint32_t vext_wd(uint32_t desc)
- }
-
- /*
- - * Get vector group length in bytes. Its range is [64, 2048].
- + * Get the maximum number of elements can be operated.
- *
- - * As simd_desc support at most 256, the max vlen is 512 bits.
- - * So vlen in bytes is encoded as maxsz.
- + * esz: log2 of element size in bytes.
- */
- -static inline uint32_t vext_maxsz(uint32_t desc)
- +static inline uint32_t vext_max_elems(uint32_t desc, uint32_t esz)
- {
- - return simd_maxsz(desc) << vext_lmul(desc);
- + /*
- + * As simd_desc support at most 256 bytes, the max vlen is 256 bits.
- + * so vlen in bytes (vlenb) is encoded as maxsz.
- + */
- + uint32_t vlenb = simd_maxsz(desc);
- +
- + /* Return VLMAX */
- + int scale = vext_lmul(desc) - esz;
- + return scale < 0 ? vlenb >> -scale : vlenb << scale;
- }
-
- /*
- @@ -221,14 +229,14 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
- {
- uint32_t i, k;
- uint32_t nf = vext_nf(desc);
- - uint32_t vlmax = vext_maxsz(desc) / esz;
- + uint32_t max_elems = vext_max_elems(desc, esz);
-
- /* probe every access*/
- for (i = 0; i < env->vl; i++) {
- if (!vm && !vext_elem_mask(v0, i)) {
- continue;
- }
- - probe_pages(env, base + stride * i, nf * esz, ra, access_type);
- + probe_pages(env, base + stride * i, nf << esz, ra, access_type);
- }
- /* do real access */
- for (i = 0; i < env->vl; i++) {
- @@ -237,8 +245,8 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
- continue;
- }
- while (k < nf) {
- - target_ulong addr = base + stride * i + k * esz;
- - ldst_elem(env, addr, i + k * vlmax, vd, ra);
- + target_ulong addr = base + stride * i + (k << esz);
- + ldst_elem(env, addr, i + k * max_elems, vd, ra);
- k++;
- }
- }
- @@ -251,7 +259,7 @@ void HELPER(NAME)(void *vd, void * v0, target_ulong base, \
- { \
- uint32_t vm = vext_vm(desc); \
- vext_ldst_stride(vd, v0, base, stride, env, desc, vm, LOAD_FN, \
- - sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \
- + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD); \
- }
-
- GEN_VEXT_LD_STRIDE(vlse8_v, int8_t, lde_b)
- @@ -266,7 +274,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base, \
- { \
- uint32_t vm = vext_vm(desc); \
- vext_ldst_stride(vd, v0, base, stride, env, desc, vm, STORE_FN, \
- - sizeof(ETYPE), GETPC(), MMU_DATA_STORE); \
- + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \
- }
-
- GEN_VEXT_ST_STRIDE(vsse8_v, int8_t, ste_b)
- @@ -286,16 +294,16 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
- {
- uint32_t i, k;
- uint32_t nf = vext_nf(desc);
- - uint32_t vlmax = vext_maxsz(desc) / esz;
- + uint32_t max_elems = vext_max_elems(desc, esz);
-
- /* probe every access */
- - probe_pages(env, base, env->vl * nf * esz, ra, access_type);
- + probe_pages(env, base, env->vl * (nf << esz), ra, access_type);
- /* load bytes from guest memory */
- for (i = 0; i < env->vl; i++) {
- k = 0;
- while (k < nf) {
- - target_ulong addr = base + (i * nf + k) * esz;
- - ldst_elem(env, addr, i + k * vlmax, vd, ra);
- + target_ulong addr = base + ((i * nf + k) << esz);
- + ldst_elem(env, addr, i + k * max_elems, vd, ra);
- k++;
- }
- }
- @@ -310,16 +318,16 @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
- void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \
- CPURISCVState *env, uint32_t desc) \
- { \
- - uint32_t stride = vext_nf(desc) * sizeof(ETYPE); \
- + uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE)); \
- vext_ldst_stride(vd, v0, base, stride, env, desc, false, LOAD_FN, \
- - sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \
- + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD); \
- } \
- \
- void HELPER(NAME)(void *vd, void *v0, target_ulong base, \
- CPURISCVState *env, uint32_t desc) \
- { \
- vext_ldst_us(vd, base, env, desc, LOAD_FN, \
- - sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \
- + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD); \
- }
-
- GEN_VEXT_LD_US(vle8_v, int8_t, lde_b)
- @@ -331,16 +339,16 @@ GEN_VEXT_LD_US(vle64_v, int64_t, lde_d)
- void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \
- CPURISCVState *env, uint32_t desc) \
- { \
- - uint32_t stride = vext_nf(desc) * sizeof(ETYPE); \
- + uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE)); \
- vext_ldst_stride(vd, v0, base, stride, env, desc, false, STORE_FN, \
- - sizeof(ETYPE), GETPC(), MMU_DATA_STORE); \
- + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \
- } \
- \
- void HELPER(NAME)(void *vd, void *v0, target_ulong base, \
- CPURISCVState *env, uint32_t desc) \
- { \
- vext_ldst_us(vd, base, env, desc, STORE_FN, \
- - sizeof(ETYPE), GETPC(), MMU_DATA_STORE); \
- + ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \
- }
-
- GEN_VEXT_ST_US(vse8_v, int8_t, ste_b)
- @@ -376,14 +384,14 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
- uint32_t i, k;
- uint32_t nf = vext_nf(desc);
- uint32_t vm = vext_vm(desc);
- - uint32_t vlmax = vext_maxsz(desc) / esz;
- + uint32_t max_elems = vext_max_elems(desc, esz);
-
- /* probe every access*/
- for (i = 0; i < env->vl; i++) {
- if (!vm && !vext_elem_mask(v0, i)) {
- continue;
- }
- - probe_pages(env, get_index_addr(base, i, vs2), nf * esz, ra,
- + probe_pages(env, get_index_addr(base, i, vs2), nf << esz, ra,
- access_type);
- }
- /* load bytes from guest memory */
- @@ -393,8 +401,8 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
- continue;
- }
- while (k < nf) {
- - abi_ptr addr = get_index_addr(base, i, vs2) + k * esz;
- - ldst_elem(env, addr, i + k * vlmax, vd, ra);
- + abi_ptr addr = get_index_addr(base, i, vs2) + (k << esz);
- + ldst_elem(env, addr, i + k * max_elems, vd, ra);
- k++;
- }
- }
- @@ -405,7 +413,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base, \
- void *vs2, CPURISCVState *env, uint32_t desc) \
- { \
- vext_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN, \
- - LOAD_FN, sizeof(ETYPE), GETPC(), MMU_DATA_LOAD); \
- + LOAD_FN, ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD); \
- }
-
- GEN_VEXT_LD_INDEX(vlxei8_8_v, int8_t, idx_b, lde_b)
- @@ -430,7 +438,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base, \
- void *vs2, CPURISCVState *env, uint32_t desc) \
- { \
- vext_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN, \
- - STORE_FN, sizeof(ETYPE), \
- + STORE_FN, ctzl(sizeof(ETYPE)), \
- GETPC(), MMU_DATA_STORE); \
- }
-
- @@ -464,7 +472,7 @@ vext_ldff(void *vd, void *v0, target_ulong base,
- uint32_t i, k, vl = 0;
- uint32_t nf = vext_nf(desc);
- uint32_t vm = vext_vm(desc);
- - uint32_t vlmax = vext_maxsz(desc) / esz;
- + uint32_t max_elems = vext_max_elems(desc, esz);
- target_ulong addr, offset, remain;
-
- /* probe every access*/
- @@ -472,24 +480,24 @@ vext_ldff(void *vd, void *v0, target_ulong base,
- if (!vm && !vext_elem_mask(v0, i)) {
- continue;
- }
- - addr = base + nf * i * esz;
- + addr = base + i * (nf << esz);
- if (i == 0) {
- - probe_pages(env, addr, nf * esz, ra, MMU_DATA_LOAD);
- + probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD);
- } else {
- /* if it triggers an exception, no need to check watchpoint */
- - remain = nf * esz;
- + remain = nf << esz;
- while (remain > 0) {
- offset = -(addr | TARGET_PAGE_MASK);
- host = tlb_vaddr_to_host(env, addr, MMU_DATA_LOAD,
- cpu_mmu_index(env, false));
- if (host) {
- #ifdef CONFIG_USER_ONLY
- - if (page_check_range(addr, nf * esz, PAGE_READ) < 0) {
- + if (page_check_range(addr, nf << esz, PAGE_READ) < 0) {
- vl = i;
- goto ProbeSuccess;
- }
- #else
- - probe_pages(env, addr, nf * esz, ra, MMU_DATA_LOAD);
- + probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD);
- #endif
- } else {
- vl = i;
- @@ -514,8 +522,8 @@ ProbeSuccess:
- continue;
- }
- while (k < nf) {
- - target_ulong addr = base + (i * nf + k) * esz;
- - ldst_elem(env, addr, i + k * vlmax, vd, ra);
- + target_ulong addr = base + ((i * nf + k) << esz);
- + ldst_elem(env, addr, i + k * max_elems, vd, ra);
- k++;
- }
- }
- @@ -526,7 +534,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base, \
- CPURISCVState *env, uint32_t desc) \
- { \
- vext_ldff(vd, v0, base, env, desc, LOAD_FN, \
- - sizeof(ETYPE), GETPC()); \
- + ctzl(sizeof(ETYPE)), GETPC()); \
- }
-
- GEN_VEXT_LDFF(vle8ff_v, int8_t, lde_b)
- @@ -739,7 +747,7 @@ void HELPER(NAME)(void *vs3, void *v0, target_ulong base, \
- { \
- vext_amo_noatomic(vs3, v0, base, vs2, env, desc, \
- INDEX_FN, vext_##NAME##_noatomic_op, \
- - sizeof(ETYPE), GETPC()); \
- + ctzl(sizeof(ETYPE)), GETPC()); \
- }
-
- GEN_VEXT_AMO(vamoswapei8_32_v, int32_t, idx_b)
- @@ -1225,7 +1233,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
- void *vs2, CPURISCVState *env, uint32_t desc) \
- { \
- uint32_t vl = env->vl; \
- - uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \
- + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \
- uint32_t i; \
- \
- for (i = 0; i < vl; i++) { \
- @@ -3880,7 +3888,7 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
- { \
- uint32_t vm = vext_vm(desc); \
- uint32_t vl = env->vl; \
- - uint32_t vlmax = vext_maxsz(desc) / sizeof(ETYPE); \
- + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \
- uint32_t i; \
- \
- for (i = 0; i < vl; i++) { \
- @@ -4666,7 +4674,7 @@ GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8)
- void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \
- CPURISCVState *env, uint32_t desc) \
- { \
- - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \
- + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \
- uint32_t vm = vext_vm(desc); \
- uint32_t vl = env->vl; \
- uint64_t index; \
- @@ -4695,7 +4703,7 @@ GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, H8)
- void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
- CPURISCVState *env, uint32_t desc) \
- { \
- - uint32_t vlmax = env_archcpu(env)->cfg.vlen; \
- + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \
- uint32_t vm = vext_vm(desc); \
- uint32_t vl = env->vl; \
- uint64_t index = s1; \
- --
- 2.33.1
|