From: Andrew Waterman Date: Wed, 20 Apr 2016 00:31:54 +0000 (-0700) Subject: Split ERET into URET, SRET, HRET, MRET X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=27e29e69cc586a7d97e2ccae2447faa79b66f7b8;p=riscv-isa-sim.git Split ERET into URET, SRET, HRET, MRET --- diff --git a/riscv/encoding.h b/riscv/encoding.h index c57804d..83ee482 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -345,12 +345,18 @@ #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 @@ -787,9 +793,12 @@ DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) 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) diff --git a/riscv/insns/ebreak.h b/riscv/insns/ebreak.h new file mode 100644 index 0000000..c22776c --- /dev/null +++ b/riscv/insns/ebreak.h @@ -0,0 +1 @@ +throw trap_breakpoint(); diff --git a/riscv/insns/ecall.h b/riscv/insns/ecall.h new file mode 100644 index 0000000..a933e4d --- /dev/null +++ b/riscv/insns/ecall.h @@ -0,0 +1,7 @@ +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(); +} diff --git a/riscv/insns/mret.h b/riscv/insns/mret.h new file mode 100644 index 0000000..fa97b2c --- /dev/null +++ b/riscv/insns/mret.h @@ -0,0 +1,9 @@ +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); diff --git a/riscv/insns/sbreak.h b/riscv/insns/sbreak.h deleted file mode 100644 index c22776c..0000000 --- a/riscv/insns/sbreak.h +++ /dev/null @@ -1 +0,0 @@ -throw trap_breakpoint(); diff --git a/riscv/insns/scall.h b/riscv/insns/scall.h deleted file mode 100644 index a933e4d..0000000 --- a/riscv/insns/scall.h +++ /dev/null @@ -1,7 +0,0 @@ -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(); -} diff --git a/riscv/insns/sret.h b/riscv/insns/sret.h index f317d14..f5e89e4 100644 --- a/riscv/insns/sret.h +++ b/riscv/insns/sret.h @@ -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(); -} - +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); diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index 1d9b301..2dfe4ed 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -126,6 +126,8 @@ riscv_insn_list = \ divu \ divuw \ divw \ + ebreak \ + ecall \ fadd_d \ fadd_s \ fclass_d \ @@ -202,6 +204,7 @@ riscv_insn_list = \ lui \ lw \ lwu \ + mret \ mul \ mulh \ mulhsu \ @@ -214,8 +217,6 @@ riscv_insn_list = \ remuw \ remw \ sb \ - sbreak \ - scall \ sc_d \ sc_w \ sd \ diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc index 51283a3..0d239d7 100644 --- a/spike_main/disasm.cc +++ b/spike_main/disasm.cc @@ -410,8 +410,12 @@ disassembler_t::disassembler_t() 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); @@ -428,7 +432,6 @@ disassembler_t::disassembler_t() 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);