#define MASK_LR_D 0xf9f0707f
#define MATCH_SC_D 0x1800302f
#define MASK_SC_D 0xf800707f
-#define MATCH_SCALL 0x73
-#define MASK_SCALL 0xffffffff
-#define MATCH_SBREAK 0x100073
-#define MASK_SBREAK 0xffffffff
+#define MATCH_ECALL 0x73
+#define MASK_ECALL 0xffffffff
+#define MATCH_EBREAK 0x100073
+#define MASK_EBREAK 0xffffffff
+#define MATCH_URET 0x200073
+#define MASK_URET 0xffffffff
#define MATCH_SRET 0x10200073
#define MASK_SRET 0xffffffff
+#define MATCH_HRET 0x20200073
+#define MASK_HRET 0xffffffff
+#define MATCH_MRET 0x30200073
+#define MASK_MRET 0xffffffff
#define MATCH_SFENCE_VM 0x10400073
#define MASK_SFENCE_VM 0xfff07fff
#define MATCH_WFI 0x10500073
DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
-DECLARE_INSN(scall, MATCH_SCALL, MASK_SCALL)
-DECLARE_INSN(sbreak, MATCH_SBREAK, MASK_SBREAK)
+DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)
+DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)
+DECLARE_INSN(uret, MATCH_URET, MASK_URET)
DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
+DECLARE_INSN(hret, MATCH_HRET, MASK_HRET)
+DECLARE_INSN(mret, MATCH_MRET, MASK_MRET)
DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM)
DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI)
DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
--- /dev/null
+throw trap_breakpoint();
--- /dev/null
+switch (STATE.prv)
+{
+ case PRV_U: throw trap_user_ecall();
+ case PRV_S: throw trap_supervisor_ecall();
+ case PRV_H: throw trap_hypervisor_ecall();
+ case PRV_M: throw trap_machine_ecall();
+}
--- /dev/null
+require_privilege(PRV_M);
+set_pc_and_serialize(p->get_state()->mepc);
+reg_t s = STATE.mstatus;
+reg_t prev_prv = get_field(s, MSTATUS_MPP);
+s = set_field(s, MSTATUS_UIE << prev_prv, get_field(s, MSTATUS_MPIE));
+s = set_field(s, MSTATUS_MPIE, 0);
+s = set_field(s, MSTATUS_MPP, PRV_U);
+p->set_privilege(prev_prv);
+p->set_csr(CSR_MSTATUS, s);
+++ /dev/null
-throw trap_breakpoint();
+++ /dev/null
-switch (STATE.prv)
-{
- case PRV_U: throw trap_user_ecall();
- case PRV_S: throw trap_supervisor_ecall();
- case PRV_H: throw trap_hypervisor_ecall();
- case PRV_M: throw trap_machine_ecall();
-}
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();
-}
-
+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, 0);
+s = set_field(s, MSTATUS_SPP, PRV_U);
+p->set_privilege(prev_prv);
p->set_csr(CSR_MSTATUS, s);
divu \
divuw \
divw \
+ ebreak \
+ ecall \
fadd_d \
fadd_s \
fclass_d \
lui \
lw \
lwu \
+ mret \
mul \
mulh \
mulhsu \
remuw \
remw \
sb \
- sbreak \
- scall \
sc_d \
sc_w \
sd \
DEFINE_RTYPE(remw);
DEFINE_RTYPE(remuw);
- DEFINE_NOARG(scall);
- DEFINE_NOARG(sbreak);
+ DEFINE_NOARG(ecall);
+ DEFINE_NOARG(ebreak);
+ DEFINE_NOARG(uret);
+ DEFINE_NOARG(sret);
+ DEFINE_NOARG(hret);
+ DEFINE_NOARG(mret);
DEFINE_NOARG(fence);
DEFINE_NOARG(fence_i);
add_insn(new disasm_insn_t("csrrwi", match_csrrwi, mask_csrrwi, {&xrd, &csr, &zimm5}));
add_insn(new disasm_insn_t("csrrsi", match_csrrsi, mask_csrrsi, {&xrd, &csr, &zimm5}));
add_insn(new disasm_insn_t("csrrci", match_csrrci, mask_csrrci, {&xrd, &csr, &zimm5}));
- DEFINE_NOARG(sret)
DEFINE_FRTYPE(fadd_s);
DEFINE_FRTYPE(fsub_s);