#define REG_RS1 0x2
#define REG_RS2 0x4
#define REG_RS3 0x8
+#define REG_RVC_RS1 0x10
+#define REG_RVC_RS2 0x20
+#define REG_RVC_RS1S 0x40
+#define REG_RVC_RS2S 0x80
+
class sv_insn_t: public insn_t
{
public:
- sv_insn_t(insn_bits_t bits, unsigned int f) :
- insn_t(bits), fimap(f),
- cached_rd(0xff), cached_rs1(0xff),
- cached_rs2(0xff), cached_rs3(0xff),
- offs_rd(0), offs_rs1(0),
- offs_rs2(0), offs_rs3(0) {}
- uint64_t rd ()
- { return _remap(insn_t::rd (), fimap & REG_RD , offs_rd , cached_rd); }
- uint64_t rs1()
- { return _remap(insn_t::rs1(), fimap & REG_RS1, offs_rs1, cached_rs1); }
- uint64_t rs2()
- { return _remap(insn_t::rs2(), fimap & REG_RS2, offs_rs2, cached_rs2); }
- uint64_t rs3()
- { return _remap(insn_t::rs3(), fimap & REG_RS3, offs_rs3, cached_rs3); }
+ sv_insn_t(processor_t *pr, insn_bits_t bits, unsigned int f,
+ uint64_t &p_rd, uint64_t &p_rs1, uint64_t &p_rs2, uint64_t &p_rs3,
+ int &o_rd, int &o_rs1, int &o_rs2, int &o_rs3) :
+ insn_t(bits), p(pr), vloop_continue(false), fimap(f),
+ offs_rd(o_rd), offs_rs1(o_rs1), offs_rs2(o_rs2), offs_rs3(o_rs3),
+ prd(p_rd), prs1(p_rs1), prs2(p_rs2), prs3(p_rs3) {}
+ uint64_t rd () { return predicated(_rd (), offs_rd, prd); }
+ uint64_t rs1() { return predicated(_rs1(), offs_rs1, prs1); }
+ uint64_t rs2() { return predicated(_rs2(), offs_rs2, prs2); }
+ uint64_t rs3() { return predicated(_rs3(), offs_rs3, prs3); }
+ uint64_t rvc_rs1 () { return predicated(_rvc_rs1 (), offs_rs1, prs1); }
+ uint64_t rvc_rs1s() { return predicated(_rvc_rs1s(), offs_rs1, prs1); }
+ uint64_t rvc_rs2 () { return predicated(_rvc_rs2 (), offs_rs2, prs2); }
+ uint64_t rvc_rs2s() { return predicated(_rvc_rs2s(), offs_rs2, prs2); }
- void reset_caches(void)
- {
- cached_rd = 0xff;
- cached_rs1 = 0xff;
- cached_rs2 = 0xff;
- cached_rs3 = 0xff;
- }
- reg_t predicate(processor_t* p, uint64_t reg, bool isint, bool &zeroing);
+ uint64_t _rd () { return _remap(insn_t::rd (), fimap & REG_RD , offs_rd); }
+ uint64_t _rs1() { return _remap(insn_t::rs1(), fimap & REG_RS1, offs_rs1); }
+ uint64_t _rs2() { return _remap(insn_t::rs2(), fimap & REG_RS2, offs_rs2); }
+ uint64_t _rs3() { return _remap(insn_t::rs3(), fimap & REG_RS3, offs_rs3); }
+ uint64_t _rvc_rs1 () { return _remap(insn_t::rvc_rs1(), fimap & REG_RVC_RS1,
+ offs_rs1); }
+ uint64_t _rvc_rs1s() { return _remap(insn_t::rvc_rs1s(), fimap & REG_RVC_RS1S,
+ offs_rs1); }
+ uint64_t _rvc_rs2 () { return _remap(insn_t::rvc_rs2(), fimap & REG_RVC_RS2,
+ offs_rs2); }
+ uint64_t _rvc_rs2s() { return _remap(insn_t::rvc_rs2s(), fimap & REG_RVC_RS2S,
+ offs_rs2); }
+
+ bool sv_check_reg(bool intreg, uint64_t reg);
+ sv_reg_entry* get_regentry(uint64_t reg, bool isint);
+ sv_pred_entry* get_predentry(uint64_t reg, bool isint);
+ reg_t predicate(uint64_t reg, bool isint, bool &zeroing);
+ void reset_vloop_check(void) { vloop_continue = false; }
+ bool stop_vloop(void);
+
+ processor_t *p;
private:
+ bool vloop_continue;
unsigned int fimap;
- uint64_t cached_rd;
- uint64_t cached_rs1;
- uint64_t cached_rs2;
- uint64_t cached_rs3;
- int offs_rd;
- int offs_rs1;
- int offs_rs2;
- int offs_rs3;
+ int &offs_rd;
+ int &offs_rs1;
+ int &offs_rs2;
+ int &offs_rs3;
+ uint64_t &prd;
+ uint64_t &prs1;
+ uint64_t &prs2;
+ uint64_t &prs3;
+
// remaps the register through the lookup table.
// will need to take the current loop index/offset somehow
uint64_t remap(uint64_t reg, bool isint, int &offs);
// cached version of remap: if remap is called multiple times
// by an emulated instruction it would increment the loop offset
// before it's supposed to.
- uint64_t _remap(uint64_t reg, bool isint, int &offs, uint64_t &cached)
+ uint64_t _remap(uint64_t reg, bool isint, int &offs)
{
- if (cached == 0xff)
+ if (sv_check_reg(isint, reg))
{
- cached = remap(reg, isint, offs);
+ vloop_continue = true;
}
- return cached;
+ return remap(reg, isint, offs);
}
+
+ uint64_t predicated(uint64_t reg, int offs, uint64_t pred);
};
#endif