aboutsummaryrefslogtreecommitdiff
path: root/riscv/processor.h
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/processor.h')
-rw-r--r--riscv/processor.h57
1 files changed, 47 insertions, 10 deletions
diff --git a/riscv/processor.h b/riscv/processor.h
index f3e5294..9b776e2 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -43,7 +43,7 @@ struct insn_desc_t
insn_func_t logged_rv32e;
insn_func_t logged_rv64e;
- insn_func_t func(int xlen, bool rve, bool logged)
+ insn_func_t func(int xlen, bool rve, bool logged) const
{
if (logged)
if (rve)
@@ -57,12 +57,7 @@ struct insn_desc_t
return xlen == 64 ? fast_rv64i : fast_rv32i;
}
- static insn_desc_t illegal()
- {
- return {0, 0,
- &illegal_instruction, &illegal_instruction, &illegal_instruction, &illegal_instruction,
- &illegal_instruction, &illegal_instruction, &illegal_instruction, &illegal_instruction};
- }
+ static const insn_desc_t illegal_instruction;
};
// regnum, data
@@ -141,6 +136,7 @@ struct state_t
dcsr_csr_t_p dcsr;
csr_t_p tselect;
csr_t_p tdata2;
+ csr_t_p tcontrol;
csr_t_p scontext;
csr_t_p mcontext;
@@ -195,6 +191,47 @@ struct state_t
elp_t elp;
};
+class opcode_cache_entry_t {
+ public:
+ opcode_cache_entry_t()
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ for (size_t i = 0; i < associativity; i++) {
+ tag[i] = 0;
+ contents[i] = &insn_desc_t::illegal_instruction;
+ }
+ }
+
+ void replace(insn_bits_t opcode, const insn_desc_t* desc)
+ {
+ for (size_t i = associativity - 1; i > 0; i--) {
+ tag[i] = tag[i-1];
+ contents[i] = contents[i-1];
+ }
+
+ tag[0] = opcode;
+ contents[0] = desc;
+ }
+
+ std::tuple<bool, const insn_desc_t*> lookup(insn_bits_t opcode)
+ {
+ for (size_t i = 0; i < associativity; i++)
+ if (tag[i] == opcode)
+ return std::tuple(true, contents[i]);
+
+ return std::tuple(false, nullptr);
+ }
+
+ private:
+ static const size_t associativity = 4;
+ insn_bits_t tag[associativity];
+ const insn_desc_t* contents[associativity];
+};
+
// this class represents one processor in a RISC-V machine.
class processor_t : public abstract_device_t
{
@@ -319,7 +356,7 @@ public:
void clear_waiting_for_interrupt() { in_wfi = false; };
bool is_waiting_for_interrupt() { return in_wfi; };
- void execute_insn_prehook(insn_t insn);
+ void check_if_lpad_required();
private:
const isa_parser_t * const isa;
@@ -350,8 +387,8 @@ private:
std::vector<insn_desc_t> custom_instructions;
std::unordered_map<reg_t,uint64_t> pc_histogram;
- static const size_t OPCODE_CACHE_SIZE = 8191;
- insn_desc_t opcode_cache[OPCODE_CACHE_SIZE];
+ static const size_t OPCODE_CACHE_SIZE = 4095;
+ opcode_cache_entry_t opcode_cache[OPCODE_CACHE_SIZE];
void take_pending_interrupt() { take_interrupt(state.mip->read() & state.mie->read()); }
void take_interrupt(reg_t mask); // take first enabled interrupt in mask