aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2026-01-04 23:06:00 -0800
committerAndrew Waterman <andrew@sifive.com>2026-01-04 23:06:00 -0800
commit60461850d11564467bec25a615128c18cacd1865 (patch)
treed1fd98bdc42f7c0ea979db5835bc873685cb8775
parentec4fcece72add22f44f08cff6f610f7d72e8b204 (diff)
downloadriscv-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.h31
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; \