From 27e29e69cc586a7d97e2ccae2447faa79b66f7b8 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 19 Apr 2016 17:31:54 -0700 Subject: [PATCH] Split ERET into URET, SRET, HRET, MRET --- riscv/encoding.h | 21 +++++++++++++++------ riscv/insns/{sbreak.h => ebreak.h} | 0 riscv/insns/{scall.h => ecall.h} | 0 riscv/insns/mret.h | 9 +++++++++ riscv/insns/sret.h | 19 ++++++------------- riscv/riscv.mk.in | 5 +++-- spike_main/disasm.cc | 9 ++++++--- 7 files changed, 39 insertions(+), 24 deletions(-) rename riscv/insns/{sbreak.h => ebreak.h} (100%) rename riscv/insns/{scall.h => ecall.h} (100%) create mode 100644 riscv/insns/mret.h 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/sbreak.h b/riscv/insns/ebreak.h similarity index 100% rename from riscv/insns/sbreak.h rename to riscv/insns/ebreak.h diff --git a/riscv/insns/scall.h b/riscv/insns/ecall.h similarity index 100% rename from riscv/insns/scall.h rename to riscv/insns/ecall.h 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/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); -- 2.30.2