diff options
| author | Andrew Waterman <andrew@sifive.com> | 2026-01-04 23:06:00 -0800 |
|---|---|---|
| committer | Andrew Waterman <andrew@sifive.com> | 2026-01-04 23:06:00 -0800 |
| commit | 60461850d11564467bec25a615128c18cacd1865 (patch) | |
| tree | d1fd98bdc42f7c0ea979db5835bc873685cb8775 | |
| parent | ec4fcece72add22f44f08cff6f610f7d72e8b204 (diff) | |
| download | riscv-isa-sim-fix-2206.zip riscv-isa-sim-fix-2206.tar.gz riscv-isa-sim-fix-2206.tar.bz2 | |
Make sure vector loads and stores set VS=Dirty, but not too earlyfix-2206
| -rw-r--r-- | riscv/v_ext_macros.h | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/riscv/v_ext_macros.h b/riscv/v_ext_macros.h index e2c29da..2ea005a 100644 --- a/riscv/v_ext_macros.h +++ b/riscv/v_ext_macros.h @@ -98,10 +98,11 @@ static inline bool is_overlapped_widen(const int astart, int asize, require_align(insn.rs2(), vemul); \ require((nf * flmul) <= (NVPR / 4) && \ (insn.rd() + nf * flmul) <= NVPR); \ + dirty_vs_state; #define VI_CHECK_LD_INDEX(elt_width) \ - VI_CHECK_ST_INDEX(elt_width); \ for (reg_t idx = 0; idx < nf; ++idx) { \ + float vemul = ((float)elt_width / P.VU.vsew * P.VU.vflmul); \ reg_t flmul = P.VU.vflmul < 1 ? 1 : P.VU.vflmul; \ reg_t seg_vd = insn.rd() + flmul * idx; \ if (elt_width > P.VU.vsew) { \ @@ -119,6 +120,7 @@ static inline bool is_overlapped_widen(const int astart, int asize, } \ } \ require_vm; \ + VI_CHECK_ST_INDEX(elt_width); \ #define VI_CHECK_MSS(is_vs1) \ if (insn.rd() != insn.rs2()) \ @@ -150,10 +152,11 @@ static inline bool is_overlapped_widen(const int astart, int asize, require((nf * emul) <= (NVPR / 4) && \ (insn.rd() + nf * emul) <= NVPR); \ require(veew <= P.VU.ELEN); \ + dirty_vs_state; #define VI_CHECK_LOAD(elt_width, is_mask_ldst) \ - VI_CHECK_STORE(elt_width, is_mask_ldst); \ require_vm; \ + VI_CHECK_STORE(elt_width, is_mask_ldst); \ #define VI_CHECK_DSS(is_vs1) \ VI_WIDE_CHECK_COMMON; \ @@ -1189,10 +1192,10 @@ VI_VX_ULOOP({ \ #define VI_LD(stride, offset, elt_width, is_mask_ldst) \ const reg_t nf = insn.v_nf() + 1; \ - VI_CHECK_LOAD(elt_width, is_mask_ldst); \ const reg_t vl = is_mask_ldst ? ((P.VU.vl->read() + 7) / 8) : P.VU.vl->read(); \ const reg_t baseAddr = RS1; \ const reg_t vd = insn.rd(); \ + VI_CHECK_LOAD(elt_width, is_mask_ldst); \ for (reg_t i = 0; i < vl; ++i) { \ VI_ELEMENT_SKIP; \ VI_STRIP(i); \ @@ -1224,12 +1227,12 @@ VI_VX_ULOOP({ \ #define VI_LD_INDEX(elt_width, is_seg) \ const reg_t nf = insn.v_nf() + 1; \ - VI_CHECK_LD_INDEX(elt_width); \ const reg_t vl = P.VU.vl->read(); \ const reg_t baseAddr = RS1; \ const reg_t vd = insn.rd(); \ if (!is_seg) \ require(nf == 1); \ + VI_CHECK_LD_INDEX(elt_width); \ for (reg_t i = 0; i < vl; ++i) { \ VI_LDST_GET_INDEX(elt_width); \ VI_ELEMENT_SKIP; \ @@ -1260,10 +1263,10 @@ VI_VX_ULOOP({ \ #define VI_ST(stride, offset, elt_width, is_mask_ldst) \ const reg_t nf = insn.v_nf() + 1; \ - VI_CHECK_STORE(elt_width, is_mask_ldst); \ const reg_t vl = is_mask_ldst ? ((P.VU.vl->read() + 7) / 8) : P.VU.vl->read(); \ const reg_t baseAddr = RS1; \ const reg_t vs3 = insn.rd(); \ + VI_CHECK_STORE(elt_width, is_mask_ldst); \ for (reg_t i = 0; i < vl; ++i) { \ VI_STRIP(i) \ VI_ELEMENT_SKIP; \ @@ -1278,12 +1281,12 @@ VI_VX_ULOOP({ \ #define VI_ST_INDEX(elt_width, is_seg) \ const reg_t nf = insn.v_nf() + 1; \ - VI_CHECK_ST_INDEX(elt_width); \ const reg_t vl = P.VU.vl->read(); \ const reg_t baseAddr = RS1; \ const reg_t vs3 = insn.rd(); \ if (!is_seg) \ require(nf == 1); \ + VI_CHECK_ST_INDEX(elt_width); \ for (reg_t i = 0; i < vl; ++i) { \ VI_LDST_GET_INDEX(elt_width); \ VI_STRIP(i) \ @@ -1314,11 +1317,11 @@ VI_VX_ULOOP({ \ #define VI_LDST_FF(elt_width) \ const reg_t nf = insn.v_nf() + 1; \ - VI_CHECK_LOAD(elt_width, false); \ const reg_t vl = p->VU.vl->read(); \ const reg_t baseAddr = RS1; \ const reg_t rd_num = insn.rd(); \ bool early_stop = false; \ + VI_CHECK_LOAD(elt_width, false); \ for (reg_t i = p->VU.vstart->read(); i < vl; ++i) { \ VI_STRIP(i); \ VI_ELEMENT_SKIP; \ @@ -1343,17 +1346,18 @@ VI_VX_ULOOP({ \ break; \ } \ } \ - p->VU.vstart->write(0); + VECTOR_END; #define VI_LD_WHOLE(elt_width) \ - require_vector_novtype(true); \ - require(sizeof(elt_width ## _t) * 8 <= P.VU.ELEN); \ const reg_t baseAddr = RS1; \ const reg_t vd = insn.rd(); \ const reg_t len = insn.v_nf() + 1; \ - require_align(vd, len); \ const reg_t elt_per_reg = P.VU.vlenb / sizeof(elt_width ## _t); \ const reg_t size = len * elt_per_reg; \ + require_vector_novtype(true); \ + require(sizeof(elt_width ## _t) * 8 <= P.VU.ELEN); \ + require_align(vd, len); \ + dirty_vs_state; \ if (P.VU.vstart->read() < size) { \ reg_t i = P.VU.vstart->read() / elt_per_reg; \ reg_t off = P.VU.vstart->read() % elt_per_reg; \ @@ -1378,12 +1382,13 @@ VI_VX_ULOOP({ \ VECTOR_END; #define VI_ST_WHOLE \ - require_vector_novtype(true); \ const reg_t baseAddr = RS1; \ const reg_t vs3 = insn.rd(); \ const reg_t len = insn.v_nf() + 1; \ - require_align(vs3, len); \ const reg_t size = len * P.VU.vlenb; \ + require_vector_novtype(true); \ + require_align(vs3, len); \ + dirty_vs_state; \ \ if (P.VU.vstart->read() < size) { \ reg_t i = P.VU.vstart->read() / P.VU.vlenb; \ |
