aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2019-12-19 23:32:03 -0800
committerGitHub <noreply@github.com>2019-12-19 23:32:03 -0800
commitd3ac85a9ddd8927986d52b6ab401052db46da912 (patch)
treebdfb95e094cd15416b66a44e766786ffa9db711a
parent363c76a8947a476d13f270dacff00430ca7c460c (diff)
parent0b27475221fc1ab370c03794f317fd2a8347f9ba (diff)
downloadriscv-isa-sim-d3ac85a9ddd8927986d52b6ab401052db46da912.zip
riscv-isa-sim-d3ac85a9ddd8927986d52b6ab401052db46da912.tar.gz
riscv-isa-sim-d3ac85a9ddd8927986d52b6ab401052db46da912.tar.bz2
Merge pull request #371 from riscv/fix-vlff
Vector load/store fixes
-rw-r--r--riscv/decode.h30
-rw-r--r--riscv/insns/vleff_v.h64
2 files changed, 28 insertions, 66 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index f8ac020..56d7ef5 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -1394,11 +1394,13 @@ for (reg_t i = 0; i < vlmax; ++i) { \
const reg_t vl = P.VU.vl; \
const reg_t baseAddr = RS1; \
const reg_t vs3 = insn.rd(); \
+ require(vs3 + nf <= NVPR); \
const reg_t vlmax = P.VU.vlmax; \
const reg_t vlmul = P.VU.vlmul; \
for (reg_t i = 0; i < vlmax && vl != 0; ++i) { \
VI_STRIP(i) \
VI_ELEMENT_SKIP(i); \
+ P.VU.vstart = i; \
for (reg_t fn = 0; fn < nf; ++fn) { \
st_width##_t val = 0; \
switch (P.VU.vsew) { \
@@ -1427,17 +1429,15 @@ for (reg_t i = 0; i < vlmax; ++i) { \
const reg_t vl = P.VU.vl; \
const reg_t baseAddr = RS1; \
const reg_t vd = insn.rd(); \
+ require(vd + nf <= NVPR); \
const reg_t vlmax = P.VU.vlmax; \
const reg_t vlmul = P.VU.vlmul; \
for (reg_t i = 0; i < vlmax && vl != 0; ++i) { \
VI_ELEMENT_SKIP(i); \
VI_STRIP(i); \
+ P.VU.vstart = i; \
for (reg_t fn = 0; fn < nf; ++fn) { \
ld_width##_t val = MMU.load_##ld_width(baseAddr + (stride) + (offset) * elt_byte); \
- if (vd + fn >= NVPR){ \
- P.VU.vstart = vreg_inx;\
- require(false); \
- } \
switch(P.VU.vsew){ \
case e8: \
P.VU.elt<uint8_t>(vd + fn * vlmul, vreg_inx) = val; \
@@ -1468,12 +1468,23 @@ for (reg_t i = 0; i < vlmax; ++i) { \
bool early_stop = false; \
const reg_t vlmax = P.VU.vlmax; \
const reg_t vlmul = P.VU.vlmul; \
+ p->VU.vstart = 0; \
for (reg_t i = 0; i < vlmax && vl != 0; ++i) { \
VI_STRIP(i); \
VI_ELEMENT_SKIP(i); \
\
for (reg_t fn = 0; fn < nf; ++fn) { \
- itype##64_t val = MMU.load_##itype##tsew(baseAddr + (i * nf + fn) * (tsew / 8)); \
+ itype##64_t val; \
+ try { \
+ val = MMU.load_##itype##tsew(baseAddr + (i * nf + fn) * (tsew / 8)); \
+ } catch (trap_t& t) { \
+ if (i == 0) \
+ throw t; /* Only take exception on zeroth element */ \
+ /* Reduce VL if an exception occurs on a later element */ \
+ early_stop = true; \
+ P.VU.vl = i; \
+ break; \
+ } \
\
switch (sew) { \
case e8: \
@@ -1489,19 +1500,12 @@ for (reg_t i = 0; i < vlmax; ++i) { \
p->VU.elt<uint64_t>(rd_num + fn * vlmul, vreg_inx) = val; \
break; \
} \
- \
- if (val == 0) { \
- p->VU.vl = i; \
- early_stop = true; \
- break; \
- } \
} \
\
if (early_stop) { \
break; \
} \
- } \
- p->VU.vstart = 0;
+ }
//
diff --git a/riscv/insns/vleff_v.h b/riscv/insns/vleff_v.h
index e858de9..af3aa25 100644
--- a/riscv/insns/vleff_v.h
+++ b/riscv/insns/vleff_v.h
@@ -1,54 +1,12 @@
-require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-const reg_t nf = insn.v_nf() + 1;
-require((nf * P.VU.vlmul) <= (NVPR / 4));
-VI_CHECK_SXX;
-const reg_t sew = P.VU.vsew;
-const reg_t vl = P.VU.vl;
-const reg_t baseAddr = RS1;
-const reg_t rd_num = insn.rd();
-bool early_stop = false;
-const reg_t vlmul = P.VU.vlmul;
-for (reg_t i = 0; i < P.VU.vlmax && vl != 0; ++i) {
- bool is_zero = false;
- VI_STRIP(i);
- VI_ELEMENT_SKIP(i);
-
- for (reg_t fn = 0; fn < nf; ++fn) {
- MMU.load_uint8(baseAddr + (i * nf + fn) * 1);
-
- switch (sew) {
- case e8:
- P.VU.elt<uint8_t>(rd_num + fn * vlmul, vreg_inx) =
- MMU.load_uint8(baseAddr + (i * nf + fn) * 1);
- is_zero = P.VU.elt<uint8_t>(rd_num + fn * vlmul, vreg_inx) == 0;
- break;
- case e16:
- P.VU.elt<uint16_t>(rd_num + fn * vlmul, vreg_inx) =
- MMU.load_uint16(baseAddr + (i * nf + fn) * 2);
- is_zero = P.VU.elt<uint16_t>(rd_num + fn * vlmul, vreg_inx) == 0;
- break;
- case e32:
- P.VU.elt<uint32_t>(rd_num + fn * vlmul, vreg_inx) =
- MMU.load_uint32(baseAddr + (i * nf + fn) * 4);
- is_zero = P.VU.elt<uint32_t>(rd_num + fn * vlmul, vreg_inx) == 0;
- break;
- case e64:
- P.VU.elt<uint64_t>(rd_num + fn * vlmul, vreg_inx) =
- MMU.load_uint64(baseAddr + (i * nf + fn) * 8);
- is_zero = P.VU.elt<uint64_t>(rd_num + fn * vlmul, vreg_inx) == 0;
- break;
- }
-
- if (is_zero) {
- P.VU.vl = i;
- early_stop = true;
- break;
- }
- }
-
- if (early_stop) {
- break;
- }
+// vle.v and vlseg[2-8]e.v
+reg_t sew = P.VU.vsew;
+
+if (sew == e8) {
+ VI_LDST_FF(int, 8);
+} else if (sew == e16) {
+ VI_LDST_FF(int, 16);
+} else if (sew == e32) {
+ VI_LDST_FF(int, 32);
+} else if (sew == e64) {
+ VI_LDST_FF(int, 64);
}
-
-P.VU.vstart = 0;