aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave.Wen <dave.wen@sifive.com>2020-05-13 20:12:22 -0700
committerDave.Wen <dave.wen@sifive.com>2020-05-13 20:12:22 -0700
commit6fe796c4443749169a224358c62a2068d679126d (patch)
treebc355a62e9de981cca7dfa06e71ee17573772829
parent170ff9c86f928479d75a08e4f72c2e7d7e5b34a0 (diff)
downloadspike-6fe796c4443749169a224358c62a2068d679126d.zip
spike-6fe796c4443749169a224358c62a2068d679126d.tar.gz
spike-6fe796c4443749169a224358c62a2068d679126d.tar.bz2
rvv: fractional_lmul when lmul < 1
-rw-r--r--riscv/decode.h8
-rw-r--r--riscv/execute.cc9
-rw-r--r--riscv/processor.cc12
-rw-r--r--riscv/processor.h1
-rw-r--r--spike_main/disasm.cc24
5 files changed, 42 insertions, 12 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 1bbc017..bf7d2ae 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -1532,11 +1532,11 @@ for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl != 0; ++i) { \
#define VI_EEW(mew, width) \
int32_t base = mew? 128 : 8; \
- int32_t shf = width? width - 5 : 0; \
- P.VU.veew = base << (shf + 1); \
+ int32_t shf = width? width - 4 : 0; \
+ P.VU.veew = base << shf; \
P.VU.vemul = ((float)P.VU.veew/P.VU.vsew) * P.VU.vlmul; \
- assert((P.VU.veew/P.VU.vemul) == (P.VU.vsew/P.VU.vlmul)); \
- if (P.VU.vemul > 8 && P.VU.vemul < (1/8)) { \
+ if ((P.VU.vemul > 8 && P.VU.vemul < (1/8)) || \
+ ((P.VU.veew/P.VU.vemul) != (P.VU.vsew/P.VU.vlmul))) { \
throw trap_illegal_instruction(0); \
}
diff --git a/riscv/execute.cc b/riscv/execute.cc
index 79d51dd..6c20e99 100644
--- a/riscv/execute.cc
+++ b/riscv/execute.cc
@@ -253,9 +253,10 @@ void processor_t::step(size_t n)
#if 1
if (debug && !state.serialized) {
prev_reg_state_t *saved = prev_state;
+ float vlmul = VU.fractional_lmul? VU.vflmul : VU.vlmul;
if (saved->VU.setvl_count != VU.setvl_count) {
- fprintf(stderr, "vconfig <- sew=%lu vlmul=%ld vlmax=%lu vl=%lu vta=%ld, vma=%ld\n",
- VU.vsew, VU.vlmul, VU.vlmax, VU.vl, VU.vta, VU.vma);
+ fprintf(stderr, "vconfig <- sew=%lu vlmul=%.3f vlmax=%lu vl=%lu vta=%ld vma=%ld\n",
+ VU.vsew, vlmul, VU.vlmax, VU.vl, VU.vta, VU.vma);
saved->VU.setvl_count = VU.setvl_count;
}
for (int i=0; i<NXPR; ++i) {
@@ -281,8 +282,8 @@ void processor_t::step(size_t n)
}
for (reg_t i=0; i<NVPR; ++i) {
if (!VU.reg_referenced[i]) continue;
- fprintf(stderr, "vconfig <- sew=%lu vlmul=%ld eew=%lu emul=%f vlmax=%lu vl=%lu\n",
- VU.vsew, VU.vlmul, VU.veew, VU.vemul, VU.vlmax, VU.vl);
+ fprintf(stderr, "vconfig <- sew=%lu vlmul=%.3f eew=%lu emul=%f vlmax=%lu vl=%lu\n",
+ VU.vsew, vlmul, VU.veew, VU.vemul, VU.vlmax, VU.vl);
for (reg_t j=0; j<VU.VLEN/32; ++j) {
uint32_t &old = saved->VU.elt<uint32_t>(i, j);
uint32_t now = VU.elt<uint32_t>(i, j);
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 4578d94..d5cbc98 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -380,8 +380,16 @@ reg_t processor_t::vectorUnit_t::set_vl(int rd, int rs1, reg_t reqVL, reg_t newT
vta = BITS(newType, 6, 6);
vma = BITS(newType, 7, 7);
vediv = 1 << BITS(newType, 9, 8);
- vlmax = fractional_lmul? (VLEN/vsew)/vlmul : VLEN/vsew * vlmul;
- vmlen = fractional_lmul? 1 : vsew / vlmul;
+
+ if (fractional_lmul) {
+ vlmax = (VLEN/vsew)/vlmul;
+ vmlen = 1;
+ vflmul = 1/(float)vlmul;
+ vlmul = 1;
+ } else {
+ vlmax = VLEN/vsew * vlmul;
+ vmlen = vsew / vlmul;
+ }
vill = !(vlmul>=1 && vlmul <=8) || vsew > ELEN || vediv != 1 || (newType >> 8) != 0;
if (vill) {
diff --git a/riscv/processor.h b/riscv/processor.h
index 166086f..a1acb89 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -447,6 +447,7 @@ public:
reg_t vediv, vsew, vlmul;
reg_t veew;
float vemul;
+ float vflmul;
reg_t vmel;
reg_t ELEN, VLEN, SLEN;
reg_t VALU;
diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc
index bae3d51..e62c985 100644
--- a/spike_main/disasm.cc
+++ b/spike_main/disasm.cc
@@ -1,6 +1,7 @@
// See LICENSE for license details.
#include "disasm.h"
+#include "assert.h"
#include <string>
#include <vector>
#include <cstdarg>
@@ -322,8 +323,27 @@ struct : public arg_t {
auto vta = insn.v_vta() == 1 ? "ta" : "tu";
auto vma = insn.v_vma() == 1 ? "ma" : "mu";
s << "e" << sew;
- if (lmul != 1)
- s << ",m" << lmul;
+ if (lmul != 1) {
+ if(insn.v_frac_lmul()) {
+ std::string lmul_str = "";
+ switch(lmul){
+ case 2:
+ lmul_str = "f2";
+ break;
+ case 4:
+ lmul_str = "f4";
+ break;
+ case 8:
+ lmul_str = "f8";
+ break;
+ default:
+ assert(true && "unsupport fractional LMUL");
+ }
+ s << ", m" << lmul_str;
+ } else {
+ s << ", m" << lmul;
+ }
+ }
s << ", " << vta << ", " << vma;
return s.str();
}