get predicated-vectorised branch working
[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 uint64_t *p_im,
26 int *o_rd, int *o_rs1, int *o_rs2, int *o_rs3, int *o_imm) :
27 insn_t(bits), p(pr), vloop_continue(false),
28 at_least_one_reg_vectorised(false), fimap(f),
29 offs_rd(o_rd), offs_rs1(o_rs1), offs_rs2(o_rs2), offs_rs3(o_rs3),
30 offs_imm(o_imm),
31 prd(p_rd), prs1(p_rs1), prs2(p_rs2), prs3(p_rs3),
32 save_branch_addr(0) {}
33
34 uint64_t _rvc_spoffs_imm(uint64_t elwidth, uint64_t baseoffs);
35 uint64_t rvc_lwsp_imm() { return _rvc_spoffs_imm(4, insn_t::rvc_lwsp_imm()); }
36 uint64_t rvc_ldsp_imm() { return _rvc_spoffs_imm(8, insn_t::rvc_ldsp_imm()); }
37 uint64_t rvc_swsp_imm() { return _rvc_spoffs_imm(4, insn_t::rvc_swsp_imm()); }
38 uint64_t rvc_sdsp_imm() { return _rvc_spoffs_imm(8, insn_t::rvc_sdsp_imm()); }
39
40 uint64_t rd () { return predicated(_rd (), *offs_rd, prd); }
41 uint64_t rs1() { return predicated(_rs1(), *offs_rs1, prs1); }
42 uint64_t rs2() { return predicated(_rs2(), *offs_rs2, prs2); }
43 uint64_t rs3() { return predicated(_rs3(), *offs_rs3, prs3); }
44 uint64_t rvc_rs1 () { return predicated(_rvc_rs1 (), *offs_rs1, prs1); }
45 uint64_t rvc_rs1s() { return predicated(_rvc_rs1s(), *offs_rs1, prs1); }
46 uint64_t rvc_rs2 () { return predicated(_rvc_rs2 (), *offs_rs2, prs2); }
47 uint64_t rvc_rs2s() { return predicated(_rvc_rs2s(), *offs_rs2, prs2); }
48
49 uint64_t _rd () { return _remap(insn_t::rd (), fimap & REG_RD , offs_rd); }
50 uint64_t _rs1() { return _remap(insn_t::rs1(), fimap & REG_RS1, offs_rs1); }
51 uint64_t _rs2() { return _remap(insn_t::rs2(), fimap & REG_RS2, offs_rs2); }
52 uint64_t _rs3() { return _remap(insn_t::rs3(), fimap & REG_RS3, offs_rs3); }
53 uint64_t _rvc_rs1 () { return _remap(insn_t::rvc_rs1(), fimap & REG_RVC_RS1,
54 offs_rs1); }
55 uint64_t _rvc_rs1s() { return _remap(insn_t::rvc_rs1s(), fimap & REG_RVC_RS1S,
56 offs_rs1); }
57 uint64_t _rvc_rs2 () { return _remap(insn_t::rvc_rs2(), fimap & REG_RVC_RS2,
58 offs_rs2); }
59 uint64_t _rvc_rs2s() { return _remap(insn_t::rvc_rs2s(), fimap & REG_RVC_RS2S,
60 offs_rs2); }
61
62 void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
63 reg_t *target_reg);
64
65 // used for predicated branches. sets bit N if val=true; clears bit N if false
66 uint64_t rd_bitset(reg_t reg, uint64_t bit, bool val);
67
68 bool sv_check_reg(bool intreg, uint64_t reg);
69 sv_reg_entry* get_regentry(uint64_t reg, bool isint);
70 sv_pred_entry* get_predentry(uint64_t reg, bool isint);
71 reg_t predicate(uint64_t reg, bool isint, bool &zeroing);
72
73 void reset_vloop_check(void) { vloop_continue = false; }
74 bool stop_vloop(void);
75
76 processor_t *p;
77
78 // cached version of remap: if remap is called multiple times
79 // by an emulated instruction it would increment the loop offset
80 // before it's supposed to.
81 uint64_t _remap(uint64_t reg, bool isint, int *offs)
82 {
83 if (sv_check_reg(isint, reg))
84 {
85 vloop_continue = true;
86 }
87 return remap(reg, isint, *offs);
88 }
89
90 uint64_t get_saved_branch_addr() { return save_branch_addr; }
91 uint64_t get_saved_branch_rd() { return save_branch_rd; }
92 uint64_t get_if_one_reg_vectorised() { return at_least_one_reg_vectorised; }
93
94 private:
95 bool vloop_continue;
96 bool at_least_one_reg_vectorised;
97 unsigned int fimap;
98 int *offs_rd;
99 int *offs_rs1;
100 int *offs_rs2;
101 int *offs_rs3;
102 int *offs_imm;
103 uint64_t &prd;
104 uint64_t &prs1;
105 uint64_t &prs2;
106 uint64_t &prs3;
107 uint64_t save_branch_addr;
108 uint64_t save_branch_rd;
109
110 // remaps the register through the lookup table.
111 // will need to take the current loop index/offset somehow
112 uint64_t remap(uint64_t reg, bool isint, int offs);
113
114 uint64_t predicated(uint64_t reg, int offs, uint64_t pred);
115 };
116
117 #endif