cache the sv redirected register values on each loop
[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
9 #define REG_RD 0x1
10 #define REG_RS1 0x2
11 #define REG_RS2 0x4
12 #define REG_RS3 0x8
13
14 class sv_insn_t: public insn_t
15 {
16 public:
17 sv_insn_t(insn_bits_t bits, unsigned int f) :
18 insn_t(bits), fimap(f),
19 cached_rd(0xff), cached_rs1(0xff),
20 cached_rs2(0xff), cached_rs3(0xff),
21 offs_rd(0), offs_rs1(0),
22 offs_rs2(0), offs_rs3(0) {}
23 uint64_t rd ()
24 { return _remap(insn_t::rd (), fimap & REG_RD , offs_rd , cached_rd); }
25 uint64_t rs1()
26 { return _remap(insn_t::rs1(), fimap & REG_RS1, offs_rs1, cached_rs1); }
27 uint64_t rs2()
28 { return _remap(insn_t::rs2(), fimap & REG_RS2, offs_rs2, cached_rs2); }
29 uint64_t rs3()
30 { return _remap(insn_t::rs3(), fimap & REG_RS3, offs_rs3, cached_rs3); }
31
32 void reset_caches(void)
33 {
34 cached_rd = 0xff;
35 cached_rs1 = 0xff;
36 cached_rs2 = 0xff;
37 cached_rs3 = 0xff;
38 }
39 private:
40 unsigned int fimap;
41 uint64_t cached_rd;
42 uint64_t cached_rs1;
43 uint64_t cached_rs2;
44 uint64_t cached_rs3;
45 int offs_rd;
46 int offs_rs1;
47 int offs_rs2;
48 int offs_rs3;
49 // remaps the register through the lookup table.
50 // will need to take the current loop index/offset somehow
51 uint64_t remap(uint64_t reg, bool isint, int &offs);
52
53 // cached version of remap: if remap is called multiple times
54 // by an emulated instruction it would increment the loop offset
55 // before it's supposed to.
56 uint64_t _remap(uint64_t reg, bool isint, int &offs, uint64_t &cached)
57 {
58 if (cached == 0xff)
59 {
60 cached = remap(reg, isint, offs);
61 }
62 return cached;
63 }
64 };
65
66 #endif