Generate instruction decoder dynamically
[riscv-isa-sim.git] / riscv / processor.h
1 // See LICENSE for license details.
2
3 #ifndef _RISCV_PROCESSOR_H
4 #define _RISCV_PROCESSOR_H
5
6 #include "decode.h"
7 #include <cstring>
8 #include "trap.h"
9 #include "config.h"
10 #include <map>
11
12 #define MAX_UTS 2048
13
14 class processor_t;
15 class mmu_t;
16 typedef reg_t (*insn_func_t)(processor_t*, insn_t, reg_t);
17 class sim_t;
18
19 // this class represents one processor in a RISC-V machine.
20 class processor_t
21 {
22 public:
23 processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id);
24 ~processor_t();
25
26 void reset(bool value);
27 void step(size_t n, bool noisy); // run for n cycles
28 void deliver_ipi(); // register an interprocessor interrupt
29 bool running() { return run; }
30 void set_pcr(int which, reg_t val);
31 void set_interrupt(int which, bool on);
32 reg_t get_pcr(int which);
33 mmu_t* get_mmu() { return &mmu; }
34
35 void register_insn(uint32_t match, uint32_t mask, insn_func_t rv32, insn_func_t rv64);
36
37 private:
38 sim_t& sim;
39 mmu_t& mmu; // main memory is always accessed via the mmu
40
41 // user-visible architected state
42 reg_t pc;
43 regfile_t<reg_t, NXPR, true> XPR;
44 regfile_t<freg_t, NFPR, false> FPR;
45 reg_t cycle;
46
47 // privileged control registers
48 reg_t epc;
49 reg_t badvaddr;
50 reg_t evec;
51 reg_t pcr_k0;
52 reg_t pcr_k1;
53 reg_t cause;
54 reg_t tohost;
55 reg_t fromhost;
56 uint32_t id;
57 uint32_t sr; // only modify the status register using set_pcr()
58 uint32_t fsr;
59 uint32_t count;
60 uint32_t compare;
61
62 bool run; // !reset
63
64 struct opcode_map_entry_t
65 {
66 uint32_t match;
67 uint32_t mask;
68 insn_func_t rv32;
69 insn_func_t rv64;
70 };
71 unsigned opcode_bits;
72 std::multimap<uint32_t, opcode_map_entry_t> opcode_map;
73
74 void take_interrupt(); // take a trap if any interrupts are pending
75 void set_fsr(uint32_t val); // set the floating-point status register
76 void take_trap(reg_t t, bool noisy); // take an exception
77 void disasm(insn_t insn, reg_t pc); // disassemble and print an instruction
78
79 // vector stuff
80 void vcfg();
81 void setvl(int vlapp);
82
83 reg_t vecbanks;
84 uint32_t vecbanks_count;
85
86 bool utmode;
87 uint32_t utidx;
88 int vlmax;
89 int vl;
90 int nxfpr_bank;
91 int nxpr_use;
92 int nfpr_use;
93 processor_t* uts[MAX_UTS];
94
95 // this constructor is used for each of the uts
96 processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id, uint32_t _utidx);
97
98 friend class sim_t;
99 friend class mmu_t;
100 friend class htif_isasim_t;
101
102 #define DECLARE_INSN(name, match, mask) \
103 reg_t rv32_ ## name(insn_t insn, reg_t pc); \
104 reg_t rv64_ ## name(insn_t insn, reg_t pc);
105 #include "opcodes.h"
106 #undef DECLARE_INSN
107
108 insn_func_t decode_insn(insn_t insn);
109 reg_t illegal_instruction(insn_t insn, reg_t pc);
110 };
111
112 #ifndef RISCV_ENABLE_RVC
113 # define set_pc(x) \
114 do { if ((x) & 3) \
115 throw trap_instruction_address_misaligned; \
116 npc = (x); \
117 } while(0)
118 #else
119 # define set_pc(x) \
120 do { if ((x) & ((sr & SR_EC) ? 1 : 3)) \
121 throw trap_instruction_address_misaligned; \
122 npc = (x); \
123 } while(0)
124 #endif
125
126 #endif