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