diff options
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | riscv/decode.h | 6 | ||||
-rw-r--r-- | riscv/insn_template.cc | 27 | ||||
-rw-r--r-- | riscv/processor.cc | 20 | ||||
-rw-r--r-- | riscv/processor.h | 21 |
5 files changed, 55 insertions, 20 deletions
@@ -10,6 +10,7 @@ completion of the US transcontinental railway. Spike supports the following RISC-V ISA features: - RV32I and RV64I base ISAs, v2.1 + - RV32E and RV64E base ISAs, v1.9 - Zifencei extension, v2.0 - Zicsr extension, v2.0 - M extension, v2.0 diff --git a/riscv/decode.h b/riscv/decode.h index 3b3cf54..0365047 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -175,7 +175,8 @@ private: #define MMU (*p->get_mmu()) #define STATE (*p->get_state()) #define FLEN (p->get_flen()) -#define READ_REG(reg) STATE.XPR[reg] +#define CHECK_REG(reg) ((void) 0) +#define READ_REG(reg) ({ CHECK_REG(reg); STATE.XPR[reg]; }) #define READ_FREG(reg) STATE.FPR[reg] #define RD READ_REG(insn.rd()) #define RS1 READ_REG(insn.rs1()) @@ -184,7 +185,7 @@ private: #define WRITE_RD(value) WRITE_REG(insn.rd(), value) #ifndef RISCV_ENABLE_COMMITLOG -# define WRITE_REG(reg, value) STATE.XPR.write(reg, value) +# define WRITE_REG(reg, value) ({ CHECK_REG(reg); STATE.XPR.write(reg, value); }) # define WRITE_FREG(reg, value) DO_WRITE_FREG(reg, freg(value)) # define WRITE_VSTATUS #else @@ -197,6 +198,7 @@ private: # define WRITE_REG(reg, value) ({ \ reg_t wdata = (value); /* value may have side effects */ \ STATE.log_reg_write[(reg) << 4] = {wdata, 0}; \ + CHECK_REG(reg); \ STATE.XPR.write(reg, wdata); \ }) # define WRITE_FREG(reg, value) ({ \ diff --git a/riscv/insn_template.cc b/riscv/insn_template.cc index b3dd330..e6a2f52 100644 --- a/riscv/insn_template.cc +++ b/riscv/insn_template.cc @@ -3,7 +3,7 @@ #include "insn_template.h" #include "insn_macros.h" -reg_t rv32_NAME(processor_t* p, insn_t insn, reg_t pc) +reg_t rv32i_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 32 reg_t npc = sext_xlen(pc + insn_length(OPCODE)); @@ -13,7 +13,30 @@ reg_t rv32_NAME(processor_t* p, insn_t insn, reg_t pc) return npc; } -reg_t rv64_NAME(processor_t* p, insn_t insn, reg_t pc) +reg_t rv64i_NAME(processor_t* p, insn_t insn, reg_t pc) +{ + #define xlen 64 + reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + #include "insns/NAME.h" + trace_opcode(p, OPCODE, insn); + #undef xlen + return npc; +} + +#undef CHECK_REG +#define CHECK_REG(reg) require((reg) < 16) + +reg_t rv32e_NAME(processor_t* p, insn_t insn, reg_t pc) +{ + #define xlen 32 + reg_t npc = sext_xlen(pc + insn_length(OPCODE)); + #include "insns/NAME.h" + trace_opcode(p, OPCODE, insn); + #undef xlen + return npc; +} + +reg_t rv64e_NAME(processor_t* p, insn_t insn, reg_t pc) { #define xlen 64 reg_t npc = sext_xlen(pc + insn_length(OPCODE)); diff --git a/riscv/processor.cc b/riscv/processor.cc index ede80fe..b956f39 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -1042,11 +1042,13 @@ insn_func_t processor_t::decode_insn(insn_t insn) size_t idx = insn.bits() % OPCODE_CACHE_SIZE; insn_desc_t desc = opcode_cache[idx]; - if (unlikely(insn.bits() != desc.match || !desc.func(xlen))) { + bool rve = extension_enabled('E'); + + if (unlikely(insn.bits() != desc.match || !desc.func(xlen, rve))) { // fall back to linear search int cnt = 0; insn_desc_t* p = &instructions[0]; - while ((insn.bits() & p->mask) != p->match || !desc.func(xlen)) + while ((insn.bits() & p->mask) != p->match || !desc.func(xlen, rve)) p++, cnt++; desc = *p; @@ -1063,7 +1065,7 @@ insn_func_t processor_t::decode_insn(insn_t insn) opcode_cache[idx].match = insn.bits(); } - return desc.func(xlen); + return desc.func(xlen, rve); } void processor_t::register_insn(insn_desc_t desc) @@ -1112,13 +1114,17 @@ void processor_t::register_base_instructions() #undef DECLARE_INSN #define DEFINE_INSN(name) \ - extern reg_t rv32_##name(processor_t*, insn_t, reg_t); \ - extern reg_t rv64_##name(processor_t*, insn_t, reg_t); \ + extern reg_t rv32i_##name(processor_t*, insn_t, reg_t); \ + extern reg_t rv64i_##name(processor_t*, insn_t, reg_t); \ + extern reg_t rv32e_##name(processor_t*, insn_t, reg_t); \ + extern reg_t rv64e_##name(processor_t*, insn_t, reg_t); \ register_insn((insn_desc_t){ \ name##_match, \ name##_mask, \ - rv32_##name, \ - rv64_##name}); + rv32i_##name, \ + rv64i_##name, \ + rv32e_##name, \ + rv64e_##name}); #include "insn_list.h" #undef DEFINE_INSN diff --git a/riscv/processor.h b/riscv/processor.h index de896bf..35f8afc 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -29,14 +29,22 @@ struct insn_desc_t { insn_bits_t match; insn_bits_t mask; - insn_func_t rv32; - insn_func_t rv64; + insn_func_t rv32i; + insn_func_t rv64i; + insn_func_t rv32e; + insn_func_t rv64e; - insn_func_t func(int xlen) { return xlen == 64 ? rv64 : rv32; } + insn_func_t func(int xlen, bool rve) + { + if (rve) + return xlen == 64 ? rv64e : rv32e; + else + return xlen == 64 ? rv64i : rv32i; + } static insn_desc_t illegal() { - return {0, 0, &illegal_instruction, &illegal_instruction}; + return {0, 0, &illegal_instruction, &illegal_instruction, &illegal_instruction, &illegal_instruction}; } }; @@ -603,9 +611,4 @@ public: vectorUnit_t VU; }; -#define REGISTER_INSN(proc, name, match, mask, archen) \ - extern reg_t rv32_##name(processor_t*, insn_t, reg_t); \ - extern reg_t rv64_##name(processor_t*, insn_t, reg_t); \ - proc->register_insn((insn_desc_t){match, mask, rv32_##name, rv64_##name,archen}); - #endif |