1 // See LICENSE for license details.
3 #ifndef _RISCV_SV_DECODE_H
4 #define _RISCV_SV_DECODE_H
14 #define REG_RVC_RS1 0x10
15 #define REG_RVC_RS2 0x20
16 #define REG_RVC_RS1S 0x40
17 #define REG_RVC_RS2S 0x80
20 class sv_insn_t
: public insn_t
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
,
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
),
31 prd(p_rd
), prs1(p_rs1
), prs2(p_rs2
), prs3(p_rs3
),
32 save_branch_addr(0) {}
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()); }
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
); }
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
,
55 uint64_t _rvc_rs1s() { return _remap(insn_t::rvc_rs1s(), fimap
& REG_RVC_RS1S
,
57 uint64_t _rvc_rs2 () { return _remap(insn_t::rvc_rs2(), fimap
& REG_RVC_RS2
,
59 uint64_t _rvc_rs2s() { return _remap(insn_t::rvc_rs2s(), fimap
& REG_RVC_RS2S
,
62 void setpc(int xlen
, int vlen
, reg_t
&npc
, reg_t addr
, uint64_t offs
,
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
);
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
);
73 void reset_vloop_check(void) { vloop_continue
= false; }
74 bool stop_vloop(void);
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
)
83 if (sv_check_reg(isint
, reg
))
85 vloop_continue
= true;
87 return remap(reg
, isint
, *offs
);
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
; }
96 bool at_least_one_reg_vectorised
;
107 uint64_t save_branch_addr
;
108 uint64_t save_branch_rd
;
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
);
114 uint64_t predicated(uint64_t reg
, int offs
, uint64_t pred
);