aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Min Chao <chihmin.chao@sifive.com>2024-05-23 02:24:15 -0700
committerChih-Min Chao <chihmin.chao@sifive.com>2024-05-23 02:24:26 -0700
commit853105c659094122ef0769780645848646a4f463 (patch)
treea24c531c55fc0531a178c8466f5b72744f99ea5b
parent2cfd5393520c0673fd0182fcca430351d9e6682d (diff)
downloadriscv-isa-sim-853105c659094122ef0769780645848646a4f463.zip
riscv-isa-sim-853105c659094122ef0769780645848646a4f463.tar.gz
riscv-isa-sim-853105c659094122ef0769780645848646a4f463.tar.bz2
zicflip: fix [ms]ret behavior
Based on Spec chapter 3.5 "An MRET or SRET instruction is used to return from a trap in M-mode or S-mode, respectively. When executing an xRET instruction, if xPP holds the value y, then ELP is set to the value of xPELP if yLPE is 1; otherwise, it is set to NO_LP_EXPECTED; xPELP is set to NO_LP_EXPECTED." The change follow the last statement after semicolon "xPELP is set to NO_LP_EXPECTED" Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
-rw-r--r--riscv/insns/mret.h2
-rw-r--r--riscv/insns/sret.h2
2 files changed, 2 insertions, 2 deletions
diff --git a/riscv/insns/mret.h b/riscv/insns/mret.h
index 1133e86..6d4d59f 100644
--- a/riscv/insns/mret.h
+++ b/riscv/insns/mret.h
@@ -11,8 +11,8 @@ s = set_field(s, MSTATUS_MPP, p->extension_enabled('U') ? PRV_U : PRV_M);
s = set_field(s, MSTATUS_MPV, 0);
if (ZICFILP_xLPE(prev_virt, prev_prv)) {
STATE.elp = static_cast<elp_t>(get_field(s, MSTATUS_MPELP));
- s = set_field(s, MSTATUS_MPELP, elp_t::NO_LP_EXPECTED);
}
+s = set_field(s, MSTATUS_MPELP, elp_t::NO_LP_EXPECTED);
STATE.mstatus->write(s);
if (STATE.mstatush) STATE.mstatush->write(s >> 32); // log mstatush change
p->set_privilege(prev_prv, prev_virt);
diff --git a/riscv/insns/sret.h b/riscv/insns/sret.h
index aeaf087..23a13b5 100644
--- a/riscv/insns/sret.h
+++ b/riscv/insns/sret.h
@@ -25,7 +25,7 @@ if (!STATE.v) {
}
if (ZICFILP_xLPE(prev_virt, prev_prv)) {
STATE.elp = static_cast<elp_t>(get_field(s, SSTATUS_SPELP));
- s = set_field(s, SSTATUS_SPELP, elp_t::NO_LP_EXPECTED);
}
+s = set_field(s, SSTATUS_SPELP, elp_t::NO_LP_EXPECTED);
STATE.sstatus->write(s);
p->set_privilege(prev_prv, prev_virt);