aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorWeiwei Li <liweiwei@iscas.ac.cn>2022-06-28 10:38:40 +0800
committerAndrew Waterman <andrew@sifive.com>2022-11-17 16:40:00 -0800
commit087626c280571b13e5ee51a3a7603c8bbd96916a (patch)
tree5c630c7ff388d119bf9ef68221a38b9679f824aa /riscv
parent1160ea7f1b1026884bef3b8ac2caf613c8e9a475 (diff)
downloadriscv-isa-sim-087626c280571b13e5ee51a3a7603c8bbd96916a.zip
riscv-isa-sim-087626c280571b13e5ee51a3a7603c8bbd96916a.tar.gz
riscv-isa-sim-087626c280571b13e5ee51a3a7603c8bbd96916a.tar.bz2
add support for zcmt
add suport for jvt: Table entries follow the current data endianness
Diffstat (limited to 'riscv')
-rw-r--r--riscv/csrs.cc24
-rw-r--r--riscv/csrs.h6
-rw-r--r--riscv/decode.h2
-rw-r--r--riscv/insns/cm_jalt.h23
-rw-r--r--riscv/mmu.h7
-rw-r--r--riscv/overlap_list.h1
-rw-r--r--riscv/processor.cc7
-rw-r--r--riscv/processor.h3
-rw-r--r--riscv/riscv.mk.in4
9 files changed, 76 insertions, 1 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc
index 93b0bae..caee943 100644
--- a/riscv/csrs.cc
+++ b/riscv/csrs.cc
@@ -1470,3 +1470,27 @@ bool scountovf_csr_t::unlogged_write(const reg_t UNUSED val) noexcept {
/* this function is unused */
return false;
}
+
+// implement class jvt_csr_t
+jvt_csr_t::jvt_csr_t(processor_t* const proc, const reg_t addr, const reg_t init):
+ basic_csr_t(proc, addr, init) {
+}
+
+void jvt_csr_t::verify_permissions(insn_t insn, bool write) const {
+ basic_csr_t::verify_permissions(insn, write);
+
+ if (proc->extension_enabled(EXT_SMSTATEEN)) {
+ if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & SSTATEEN0_JVT))
+ throw trap_illegal_instruction(insn.bits());
+
+ if (state->v && !(state->hstateen[0]->read() & SSTATEEN0_JVT))
+ throw trap_virtual_instruction(insn.bits());
+
+ if ((proc->extension_enabled('S') && state->prv < PRV_S) && !(state->sstateen[0]->read() & SSTATEEN0_JVT)) {
+ if (state->v)
+ throw trap_virtual_instruction(insn.bits());
+ else
+ throw trap_illegal_instruction(insn.bits());
+ }
+ }
+}
diff --git a/riscv/csrs.h b/riscv/csrs.h
index 70fa2f4..b991efd 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -748,4 +748,10 @@ class scountovf_csr_t: public csr_t {
protected:
virtual bool unlogged_write(const reg_t val) noexcept override;
};
+
+class jvt_csr_t: public basic_csr_t {
+ public:
+ jvt_csr_t(processor_t* const proc, const reg_t addr, const reg_t init);
+ virtual void verify_permissions(insn_t insn, bool write) const override;
+};
#endif
diff --git a/riscv/decode.h b/riscv/decode.h
index ffc5d58..40111bc 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -131,6 +131,8 @@ public:
uint64_t rvc_rlist() { return x(4, 4); }
uint64_t rvc_spimm() { return x(2, 2) << 4; }
+ uint64_t rvc_index() { return x(2, 8); }
+
uint64_t v_vm() { return x(25, 1); }
uint64_t v_wd() { return x(26, 1); }
uint64_t v_nf() { return x(29, 3); }
diff --git a/riscv/insns/cm_jalt.h b/riscv/insns/cm_jalt.h
new file mode 100644
index 0000000..163adaa
--- /dev/null
+++ b/riscv/insns/cm_jalt.h
@@ -0,0 +1,23 @@
+require_extension(EXT_ZCMT);
+STATE.jvt->verify_permissions(insn, false);
+reg_t jvt = STATE.jvt->read();
+uint8_t mode = get_field(jvt, JVT_MODE);
+reg_t base = get_field(jvt, JVT_BASE);
+reg_t index = insn.rvc_index();
+reg_t target;
+switch (mode) {
+case 0: // jump table mode
+ if (xlen == 32)
+ target = MMU.fetch_jump_table<int32_t>(base + (index << 2));
+ else // xlen = 64
+ target = MMU.fetch_jump_table<int64_t>(base + (index << 3));
+
+ if (index >= 32) // cm.jalt
+ WRITE_REG(1, npc);
+
+ set_pc(target & ~reg_t(1));
+ break;
+default:
+ require(0);
+ break;
+}
diff --git a/riscv/mmu.h b/riscv/mmu.h
index cee93e3..dd15b79 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -225,6 +225,13 @@ public:
return (addr / PC_ALIGN) % ICACHE_ENTRIES;
}
+ template<typename T>
+ T ALWAYS_INLINE fetch_jump_table(reg_t addr) {
+ target_endian<T> res;
+ load_slow_path_intrapage(addr, sizeof(T), (uint8_t*)&res, 0);
+ return from_target(res);
+ }
+
inline icache_entry_t* refill_icache(reg_t addr, icache_entry_t* entry)
{
if (matched_trigger)
diff --git a/riscv/overlap_list.h b/riscv/overlap_list.h
index e053191..fc3b307 100644
--- a/riscv/overlap_list.h
+++ b/riscv/overlap_list.h
@@ -7,4 +7,5 @@ DECLARE_OVERLAP_INSN(cm_popret, EXT_ZCMP)
DECLARE_OVERLAP_INSN(cm_popretz, EXT_ZCMP)
DECLARE_OVERLAP_INSN(cm_mva01s, EXT_ZCMP)
DECLARE_OVERLAP_INSN(cm_mvsa01, EXT_ZCMP)
+DECLARE_OVERLAP_INSN(cm_jalt, EXT_ZCMT)
DECLARE_OVERLAP_INSN(c_fsd, EXT_ZCD)
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 0c9da97..0bf6b0e 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -450,7 +450,9 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
}
}
if (proc->extension_enabled_const(EXT_SMSTATEEN)) {
- const reg_t sstateen0_mask = (proc->extension_enabled(EXT_ZFINX) ? SSTATEEN0_FCSR : 0) | SSTATEEN0_CS;
+ const reg_t sstateen0_mask = (proc->extension_enabled(EXT_ZFINX) ? SSTATEEN0_FCSR : 0) |
+ (proc->extension_enabled(EXT_ZCMT) ? SSTATEEN0_JVT : 0) |
+ SSTATEEN0_CS;
const reg_t hstateen0_mask = sstateen0_mask | HSTATEEN0_SENVCFG | HSTATEEN_SSTATEEN;
const reg_t mstateen0_mask = hstateen0_mask;
for (int i = 0; i < 4; i++) {
@@ -492,6 +494,9 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
}
}
+ if (proc->extension_enabled_const(EXT_ZCMT))
+ csrmap[CSR_JVT] = jvt = std::make_shared<jvt_csr_t>(proc, CSR_JVT, 0);
+
serialized = false;
#ifdef RISCV_ENABLE_COMMITLOG
diff --git a/riscv/processor.h b/riscv/processor.h
index a660399..e531852 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -175,6 +175,9 @@ struct state_t
dcsr_csr_t_p dcsr;
csr_t_p tselect;
tdata2_csr_t_p tdata2;
+
+ csr_t_p jvt;
+
bool debug_mode;
mseccfg_csr_t_p mseccfg;
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index 746b916..7e38aca 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -1318,9 +1318,13 @@ riscv_insn_ext_zcmp = \
cm_mva01s \
cm_mvsa01 \
+riscv_insn_ext_zcmt = \
+ cm_jalt \
+
riscv_insn_ext_zce = \
$(riscv_insn_ext_zcb) \
$(riscv_insn_ext_zcmp) \
+ $(riscv_insn_ext_zcmt) \
riscv_insn_ext_cmo = \
cbo_clean \