Implement mstatus.TW, mstatus.TVM, and mstatus.TSR
[riscv-isa-sim.git] / riscv / insns / sret.h
index f317d14f13e1e91c7afca59b25ff9d06db5a1cef..e4d05023b6d4c83ab80c09157a4ec2fa4e4c30a3 100644 (file)
@@ -1,16 +1,9 @@
-require_privilege(PRV_S);
-switch (STATE.prv)
-{
-  case PRV_S: set_pc_and_serialize(p->get_state()->sepc); break;
-  case PRV_M: set_pc_and_serialize(p->get_state()->mepc); break;
-  default: abort();
-}
-
+require_privilege(get_field(STATE.mstatus, MSTATUS_TSR) ? PRV_M : PRV_S);
+set_pc_and_serialize(p->get_state()->sepc);
 reg_t s = STATE.mstatus;
-reg_t pie = get_field(s, MSTATUS_UPIE << STATE.prv);
-reg_t prev_prv = get_field(s, STATE.prv == PRV_S ? MSTATUS_SPP : MSTATUS_MPP);
-s = set_field(s, MSTATUS_UIE << prev_prv, pie); // [[prv]PP]IE = [prv]PIE
-s = set_field(s, MSTATUS_UPIE << STATE.prv, 0); // [prv]PIE <- 0
-s = set_field(s, STATE.prv == PRV_S ? MSTATUS_SPP : MSTATUS_MPP, PRV_U); // [prv]PP = U
-p->set_privilege(prev_prv); // prv <- [prv]PP
+reg_t prev_prv = get_field(s, MSTATUS_SPP);
+s = set_field(s, MSTATUS_UIE << prev_prv, get_field(s, MSTATUS_SPIE));
+s = set_field(s, MSTATUS_SPIE, 1);
+s = set_field(s, MSTATUS_SPP, PRV_U);
+p->set_privilege(prev_prv);
 p->set_csr(CSR_MSTATUS, s);