use an alternative logic for detecting scalar / loop-end
[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 insn_t(bits), p(pr), vloop_continue(true), fimap(f),
25 cached_rd(0xff), cached_rs1(0xff),
26 cached_rs2(0xff), cached_rs3(0xff),
27 offs_rd(0), offs_rs1(0),
28 offs_rs2(0), offs_rs3(0) {}
29 uint64_t rd ()
30 { return _remap(insn_t::rd (), fimap & REG_RD , offs_rd , cached_rd); }
31 uint64_t rs1()
32 { return _remap(insn_t::rs1(), fimap & REG_RS1, offs_rs1, cached_rs1); }
33 uint64_t rs2()
34 { return _remap(insn_t::rs2(), fimap & REG_RS2, offs_rs2, cached_rs2); }
35 uint64_t rs3()
36 { return _remap(insn_t::rs3(), fimap & REG_RS3, offs_rs3, cached_rs3); }
37 uint64_t rvc_rs1 ()
38 { return _remap(insn_t::rvc_rs1(), fimap & REG_RVC_RS1,
39 offs_rs1, cached_rs1); }
40 uint64_t rvc_rs1s ()
41 { return _remap(insn_t::rvc_rs1s(), fimap & REG_RVC_RS1S,
42 offs_rs1, cached_rs1); }
43 uint64_t rvc_rs2 ()
44 { return _remap(insn_t::rvc_rs2(), fimap & REG_RVC_RS2,
45 offs_rs2, cached_rs2); }
46 uint64_t rvc_rs2s ()
47 { return _remap(insn_t::rvc_rs2s(), fimap & REG_RVC_RS2S,
48 offs_rs2, cached_rs2); }
49
50 void reset_caches(void)
51 {
52 cached_rd = 0xff;
53 cached_rs1 = 0xff;
54 cached_rs2 = 0xff;
55 cached_rs3 = 0xff;
56 }
57
58 bool sv_check_reg(bool intreg, uint64_t reg);
59 sv_reg_entry* get_regentry(uint64_t reg, bool isint);
60 sv_pred_entry* get_predentry(uint64_t reg, bool isint);
61 reg_t predicate(uint64_t reg, bool isint, bool &zeroing);
62
63 void reset_vloop_check(void) { vloop_continue = true; }
64 bool stop_vloop(void) { return !vloop_continue; }
65
66 private:
67 processor_t *p;
68 bool vloop_continue;
69 unsigned int fimap;
70 uint64_t cached_rd;
71 uint64_t cached_rs1;
72 uint64_t cached_rs2;
73 uint64_t cached_rs3;
74 int offs_rd;
75 int offs_rs1;
76 int offs_rs2;
77 int offs_rs3;
78 // remaps the register through the lookup table.
79 // will need to take the current loop index/offset somehow
80 uint64_t remap(uint64_t reg, bool isint, int &offs);
81
82 // cached version of remap: if remap is called multiple times
83 // by an emulated instruction it would increment the loop offset
84 // before it's supposed to.
85 uint64_t _remap(uint64_t reg, bool isint, int &offs, uint64_t &cached)
86 {
87 if (cached == 0xff)
88 {
89 cached = remap(reg, isint, offs);
90 }
91 else if (!sv_check_reg(isint, reg))
92 {
93 vloop_continue = false;
94 }
95 return cached;
96 }
97 };
98
99 #endif