+ // control and status registers
+ reg_t prv; // TODO: Can this be an enum instead?
+ reg_t mstatus;
+ reg_t mepc;
+ reg_t mtval;
+ reg_t mscratch;
+ reg_t mtvec;
+ reg_t mcause;
+ reg_t minstret;
+ reg_t mie;
+ reg_t mip;
+ reg_t medeleg;
+ reg_t mideleg;
+ uint32_t mcounteren;
+ uint32_t scounteren;
+ reg_t sepc;
+ reg_t stval;
+ reg_t sscratch;
+ reg_t stvec;
+ reg_t satp;
+ reg_t scause;
+ reg_t dpc;
+ reg_t dscratch;
+ dcsr_t dcsr;
+ reg_t tselect;
+ mcontrol_t mcontrol[num_triggers];
+ reg_t tdata2[num_triggers];
+
+ uint32_t fflags;
+ uint32_t frm;
+ bool serialized; // whether timer CSRs are in a well-defined state
+
+ // When true, execute a single instruction and then enter debug mode. This
+ // can only be set by executing dret.
+ enum {
+ STEP_NONE,
+ STEP_STEPPING,
+ STEP_STEPPED
+ } single_step;
+
+ reg_t load_reservation;
+
+#ifdef RISCV_ENABLE_COMMITLOG
+ commit_log_reg_t log_reg_write;
+ reg_t last_inst_priv;
+ int last_inst_xlen;
+ int last_inst_flen;
+#endif
+};
+
+typedef enum {
+ OPERATION_EXECUTE,
+ OPERATION_STORE,
+ OPERATION_LOAD,
+} trigger_operation_t;
+
+// Count number of contiguous 1 bits starting from the LSB.
+static int cto(reg_t val)
+{
+ int res = 0;
+ while ((val & 1) == 1)
+ val >>= 1, res++;
+ return res;
+}
+
+// this class represents one processor in a RISC-V machine.
+class processor_t : public abstract_device_t
+{
+public:
+ processor_t(const char* isa, sim_t* sim, uint32_t id, bool halt_on_reset=false);
+ ~processor_t();
+
+ void set_debug(bool value);
+ void set_histogram(bool value);
+ void reset();
+ void step(size_t n); // run for n cycles
+ void set_csr(int which, reg_t val);
+ reg_t get_csr(int which);
+ mmu_t* get_mmu() { return mmu; }
+ state_t* get_state() { return &state; }
+ unsigned get_xlen() { return xlen; }
+ unsigned get_flen() {
+ return supports_extension('Q') ? 128 :
+ supports_extension('D') ? 64 :
+ supports_extension('F') ? 32 : 0;
+ }
+ extension_t* get_extension() { return ext; }
+ bool supports_extension(unsigned char ext) {
+ if (ext >= 'a' && ext <= 'z') ext += 'A' - 'a';
+ return ext >= 'A' && ext <= 'Z' && ((isa >> (ext - 'A')) & 1);
+ }
+ void check_pc_alignment(reg_t pc) {
+ if (unlikely(pc & 2) && !supports_extension('C'))
+ throw trap_instruction_address_misaligned(pc);
+ }
+ reg_t legalize_privilege(reg_t);
+ void set_privilege(reg_t);
+ void yield_load_reservation() { state.load_reservation = (reg_t)-1; }
+ void update_histogram(reg_t pc);
+ const disassembler_t* get_disassembler() { return disassembler; }
+
+ void register_insn(insn_desc_t);
+ void register_extension(extension_t*);