start work on parallelsing LOAD, pass in parameter to reinterpret immed
[riscv-isa-sim.git] / riscv / sv_decode.h
1 // See LICENSE for license details.
2
3 #ifndef _RISCV_SV_DECODE_H
4 #define _RISCV_SV_DECODE_H
5
6 #include "sv.h"
7 #include "decode.h"
8 #include "processor.h"
9
10 #define REG_RD 0x1
11 #define REG_RS1 0x2
12 #define REG_RS2 0x4
13 #define REG_RS3 0x8
14 #define REG_RVC_RS1 0x10
15 #define REG_RVC_RS2 0x20
16 #define REG_RVC_RS1S 0x40
17 #define REG_RVC_RS2S 0x80
18
19
20 class sv_insn_t: public insn_t
21 {
22 public:
23 sv_insn_t(processor_t *pr, insn_bits_t bits, unsigned int f,
24 uint64_t &p_rd, uint64_t &p_rs1, uint64_t &p_rs2, uint64_t &p_rs3,
25 bool ldimm_mode) :
26 insn_t(bits), p(pr), vloop_continue(false), fimap(f),
27 cached_rd(0xff), cached_rs1(0xff),
28 cached_rs2(0xff), cached_rs3(0xff),
29 offs_rd(0), offs_rs1(0),
30 offs_rs2(0), offs_rs3(0),
31 new_offs_rd(0), new_offs_rs1(0),
32 new_offs_rs2(0), new_offs_rs3(0),
33 prd(p_rd), prs1(p_rs1), prs2(p_rs2), prs3(p_rs3),
34 ldst_imm_mode(ldimm_mode) {}
35 uint64_t rd () { return predicated(_rd (), offs_rd , prd); }
36 uint64_t rs1() { return predicated(_rs1(), offs_rs1, prs1); }
37 uint64_t rs2() { return predicated(_rs2(), offs_rs2, prs2); }
38 uint64_t rs3() { return predicated(_rs3(), offs_rs3, prs3); }
39 uint64_t rvc_rs1 () { return predicated(_rvc_rs1 (), offs_rs1, prs1); }
40 uint64_t rvc_rs1s() { return predicated(_rvc_rs1s(), offs_rs1, prs1); }
41 uint64_t rvc_rs2 () { return predicated(_rvc_rs2 (), offs_rs2, prs2); }
42 uint64_t rvc_rs2s() { return predicated(_rvc_rs2s(), offs_rs2, prs2); }
43 uint64_t i_imm();
44
45 uint64_t _rd () { return _remap(insn_t::rd (), fimap & REG_RD ,
46 offs_rd , cached_rd, new_offs_rd); }
47 uint64_t _rs1() { return _remap(insn_t::rs1(), fimap & REG_RS1,
48 offs_rs1, cached_rs1, new_offs_rs1); }
49 uint64_t _rs2() { return _remap(insn_t::rs2(), fimap & REG_RS2,
50 offs_rs2, cached_rs2, new_offs_rs2); }
51 uint64_t _rs3() { return _remap(insn_t::rs3(), fimap & REG_RS3,
52 offs_rs3, cached_rs3, new_offs_rs3); }
53 uint64_t _rvc_rs1 () { return _remap(insn_t::rvc_rs1(), fimap & REG_RVC_RS1,
54 offs_rs1, cached_rs1, new_offs_rs1); }
55 uint64_t _rvc_rs1s() { return _remap(insn_t::rvc_rs1s(), fimap & REG_RVC_RS1S,
56 offs_rs1, cached_rs1, new_offs_rs1); }
57 uint64_t _rvc_rs2 () { return _remap(insn_t::rvc_rs2(), fimap & REG_RVC_RS2,
58 offs_rs2, cached_rs2, new_offs_rs2); }
59 uint64_t _rvc_rs2s() { return _remap(insn_t::rvc_rs2s(), fimap & REG_RVC_RS2S,
60 offs_rs2, cached_rs2, new_offs_rs2); }
61
62 void reset_caches(void)
63 {
64 cached_rd = 0xff;
65 cached_rs1 = 0xff;
66 cached_rs2 = 0xff;
67 cached_rs3 = 0xff;
68 offs_rd = new_offs_rd;
69 offs_rs1 = new_offs_rs1;
70 offs_rs2 = new_offs_rs2;
71 offs_rs3 = new_offs_rs3;
72 }
73
74 bool sv_check_reg(bool intreg, uint64_t reg);
75 sv_reg_entry* get_regentry(uint64_t reg, bool isint);
76 sv_pred_entry* get_predentry(uint64_t reg, bool isint);
77 reg_t predicate(uint64_t reg, bool isint, bool &zeroing);
78
79 void reset_vloop_check(void) { vloop_continue = false; }
80 bool stop_vloop(void) { return !vloop_continue; }
81
82 private:
83 processor_t *p;
84 bool vloop_continue;
85 unsigned int fimap;
86 uint64_t cached_rd;
87 uint64_t cached_rs1;
88 uint64_t cached_rs2;
89 uint64_t cached_rs3;
90 int offs_rd;
91 int offs_rs1;
92 int offs_rs2;
93 int offs_rs3;
94 int new_offs_rd;
95 int new_offs_rs1;
96 int new_offs_rs2;
97 int new_offs_rs3;
98 uint64_t &prd;
99 uint64_t &prs1;
100 uint64_t &prs2;
101 uint64_t &prs3;
102 bool ldst_imm_mode;
103
104 // remaps the register through the lookup table.
105 // will need to take the current loop index/offset somehow
106 uint64_t remap(uint64_t reg, bool isint, int &offs, int &newoffs);
107
108 // cached version of remap: if remap is called multiple times
109 // by an emulated instruction it would increment the loop offset
110 // before it's supposed to.
111 uint64_t _remap(uint64_t reg, bool isint, int &offs,
112 uint64_t &cached, int &newoffs)
113 {
114 if (cached == 0xff)
115 {
116 cached = remap(reg, isint, offs, newoffs);
117 }
118 else
119 {
120 if (sv_check_reg(isint, reg))
121 {
122 vloop_continue = true;
123 }
124 }
125 return cached;
126 }
127
128 uint64_t predicated(uint64_t reg, int offs, uint64_t pred);
129 };
130
131 #endif