820faaba7efa9a649991e60e53f2ee8e39b1ffe6
[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 memset(this, 0, sizeof(*this));
24 }
25
26 void hwacha_t::reset()
27 {
28 ct_state.reset();
29 for (int i=0; i<max_uts; i++)
30 ut_state[i].reset();
31 }
32
33 static reg_t custom(processor_t* p, insn_t insn, reg_t pc)
34 {
35 require_accelerator;
36 hwacha_t* h = static_cast<hwacha_t*>(p->get_extension());
37 bool matched = false;
38 reg_t npc = -1;
39
40 try
41 {
42 #define DECLARE_INSN(name, match, mask) \
43 extern reg_t hwacha_##name(processor_t*, insn_t, reg_t); \
44 if ((insn.bits() & mask) == match) { \
45 npc = hwacha_##name(p, insn, pc); \
46 matched = true; \
47 }
48 #include "opcodes_hwacha.h"
49 #undef DECLARE_INSN
50 }
51 catch (trap_instruction_access_fault& t)
52 {
53 h->take_exception(HWACHA_CAUSE_VF_FAULT_FETCH, h->get_ct_state()->vf_pc);
54 }
55 catch (trap_illegal_instruction& t)
56 {
57 h->take_exception(HWACHA_CAUSE_VF_ILLEGAL_INSTRUCTION, h->get_ct_state()->vf_pc);
58 }
59 catch (trap_load_address_misaligned& t)
60 {
61 h->take_exception(HWACHA_CAUSE_MISALIGNED_LOAD, t.get_badvaddr());
62 }
63 catch (trap_store_address_misaligned& t)
64 {
65 h->take_exception(HWACHA_CAUSE_MISALIGNED_STORE, t.get_badvaddr());
66 }
67 catch (trap_load_access_fault& t)
68 {
69 h->take_exception(HWACHA_CAUSE_FAULT_LOAD, t.get_badvaddr());
70 }
71 catch (trap_store_access_fault& t)
72 {
73 h->take_exception(HWACHA_CAUSE_FAULT_STORE, t.get_badvaddr());
74 }
75
76 if (!matched)
77 h->take_exception(HWACHA_CAUSE_ILLEGAL_INSTRUCTION, uint32_t(insn.bits()));
78
79 return npc;
80 }
81
82 std::vector<insn_desc_t> hwacha_t::get_instructions()
83 {
84 std::vector<insn_desc_t> insns;
85 insns.push_back((insn_desc_t){0x0b, 0x7f, &::illegal_instruction, custom});
86 insns.push_back((insn_desc_t){0x2b, 0x7f, &::illegal_instruction, custom});
87 insns.push_back((insn_desc_t){0x5b, 0x7f, &::illegal_instruction, custom});
88 insns.push_back((insn_desc_t){0x7b, 0x7f, &::illegal_instruction, custom});
89 return insns;
90 }
91
92 bool hwacha_t::vf_active()
93 {
94 for (uint32_t i=0; i<get_ct_state()->vl; i++) {
95 if (get_ut_state(i)->run)
96 return true;
97 }
98 return false;
99 }
100
101 void hwacha_t::take_exception(reg_t c, reg_t a)
102 {
103 cause = c;
104 aux = a;
105 raise_interrupt();
106 throw std::logic_error("unreachable!");
107 }