Factor out the dummy RoCC accelerator
[riscv-isa-sim.git] / hwacha / hwacha.cc
1 #include "hwacha.h"
2 #include "hwacha_xcpt.h"
3 #include "mmu.h"
4 #include "trap.h"
5 #include <stdexcept>
6
7 REGISTER_EXTENSION(hwacha, []() { return new hwacha_t; })
8
9 void ct_state_t::reset()
10 {
11 nxpr = 32;
12 nfpr = 32;
13 maxvl = 32;
14 vl = 0;
15 count = 0;
16 prec = 64;
17
18 vf_pc = -1;
19 }
20
21 void ut_state_t::reset()
22 {
23 run = false;
24 XPR.reset();
25 FPR.reset();
26 }
27
28 void hwacha_t::reset()
29 {
30 ct_state.reset();
31 for (int i=0; i<max_uts; i++)
32 ut_state[i].reset();
33 }
34
35 static reg_t custom(processor_t* p, insn_t insn, reg_t pc)
36 {
37 require_accelerator;
38 hwacha_t* h = static_cast<hwacha_t*>(p->get_extension());
39 bool matched = false;
40 reg_t npc = -1;
41
42 try
43 {
44 #define DECLARE_INSN(name, match, mask) \
45 extern reg_t hwacha_##name(processor_t*, insn_t, reg_t); \
46 if ((insn.bits() & mask) == match) { \
47 npc = hwacha_##name(p, insn, pc); \
48 matched = true; \
49 }
50 #include "opcodes_hwacha.h"
51 #undef DECLARE_INSN
52 }
53 catch (trap_instruction_access_fault& t)
54 {
55 h->take_exception(HWACHA_CAUSE_VF_FAULT_FETCH, h->get_ct_state()->vf_pc);
56 }
57 catch (trap_illegal_instruction& t)
58 {
59 h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_INSTRUCTION, h->get_ct_state()->vf_pc);
60 }
61 catch (trap_load_address_misaligned& t)
62 {
63 h->take_exception(HWACHA_CAUSE_MISALIGNED_LOAD, t.get_badvaddr());
64 }
65 catch (trap_store_address_misaligned& t)
66 {
67 h->take_exception(HWACHA_CAUSE_MISALIGNED_STORE, t.get_badvaddr());
68 }
69 catch (trap_load_access_fault& t)
70 {
71 h->take_exception(HWACHA_CAUSE_FAULT_LOAD, t.get_badvaddr());
72 }
73 catch (trap_store_access_fault& t)
74 {
75 h->take_exception(HWACHA_CAUSE_FAULT_STORE, t.get_badvaddr());
76 }
77
78 if (!matched)
79 h->take_exception(HWACHA_CAUSE_ILLEGAL_INSTRUCTION, insn.bits());
80
81 return npc;
82 }
83
84 std::vector<insn_desc_t> hwacha_t::get_instructions()
85 {
86 std::vector<insn_desc_t> insns;
87 insns.push_back((insn_desc_t){0x0b, 0x7f, &::illegal_instruction, custom});
88 insns.push_back((insn_desc_t){0x2b, 0x7f, &::illegal_instruction, custom});
89 insns.push_back((insn_desc_t){0x5b, 0x7f, &::illegal_instruction, custom});
90 insns.push_back((insn_desc_t){0x7b, 0x7f, &::illegal_instruction, custom});
91 return insns;
92 }
93
94 bool hwacha_t::vf_active()
95 {
96 for (uint32_t i=0; i<get_ct_state()->vl; i++) {
97 if (get_ut_state(i)->run)
98 return true;
99 }
100 return false;
101 }
102
103 void hwacha_t::take_exception(reg_t c, reg_t a)
104 {
105 cause = c;
106 aux = a;
107 raise_interrupt();
108 if (!(p->get_state()->sr & SR_EI))
109 throw std::logic_error("hwacha exception posted, but SR_EI bit not set!");
110 throw std::logic_error("hwacha exception posted, but IM[COP] bit not set!");
111 }