s_insn.rd(), s_insn.rs1(), s_insn.rs2(),
vlen);
#ifdef INSN_TYPE_C_STACK_LD
- sp = insn._remap(X_SP, true, src_offs);
+ sp = insn._remap(X_SP, true, src_offs, src_subo);
#endif
#ifdef INSN_TYPE_C_STACK_ST
- sp = insn._remap(X_SP, true, dest_offs);
+ sp = insn._remap(X_SP, true, dest_offs, dest_subo);
#endif
#ifdef INSN_TYPE_BRANCH
// all branch ops are rs1, rs2. take target (dest) predicate from rs2.
* of SV. it's "supposed" to "just" be a vectorisation API. it isn't:
* it's quite a bit more.
*/
-reg_spec_t sv_insn_t::remap(uint64_t reg, bool intreg, int *voffs)
+reg_spec_t sv_insn_t::remap(uint64_t reg, bool intreg, int *voffs, int *subo)
{
reg_spec_t spec = {reg, NULL};
// okaay so first determine which map to use. intreg is passed
// aaand now, as it's a "vector", FINALLY we can pass the loop-offset
spec.reg = reg; //+ *voffs;
spec.offset = voffs;
+ spec.suboff = subo;
spec.isvec = r->isvec;
spec.signextend = signextended;
return spec;
fprintf(stderr, "predication %ld %d %lx\n", spec.reg, (*spec.offset), pred);
res.reg = 0;
res.offset = 0;
+ res.suboff = 0;
res.isvec = spec.isvec;
return res;
}
reg_spec_t rvc_sp (bool use_offs=true)
{ return predicated(_rvc_sp (use_offs), psp ); }
- reg_spec_t _rd () { return _remap(insn_t::rd (), fimap & REG_RD , offs_rd); }
- reg_spec_t _rs1() { return _remap(insn_t::rs1(), fimap & REG_RS1, offs_rs1); }
- reg_spec_t _rs2() { return _remap(insn_t::rs2(), fimap & REG_RS2, offs_rs2); }
- reg_spec_t _rs3() { return _remap(insn_t::rs3(), fimap & REG_RS3, offs_rs3); }
- reg_spec_t _rvc_rs1 () { return _remap(insn_t::rvc_rs1(), fimap & REG_RVC_RS1,
- offs_rs1); }
- reg_spec_t _rvc_rs1s() { return _remap(insn_t::rvc_rs1s(), fimap & REG_RVC_RS1S,
- offs_rs1); }
- reg_spec_t _rvc_rs2 () { return _remap(insn_t::rvc_rs2(), fimap & REG_RVC_RS2,
- offs_rs2); }
- reg_spec_t _rvc_rs2s() { return _remap(insn_t::rvc_rs2s(), fimap & REG_RVC_RS2S,
- offs_rs2); }
+ reg_spec_t _rd () { return _remap(insn_t::rd (), fimap & REG_RD,
+ offs_rd, subo_rd); }
+ reg_spec_t _rs1() { return _remap(insn_t::rs1(), fimap & REG_RS1,
+ offs_rs1, subo_rs1); }
+ reg_spec_t _rs2() { return _remap(insn_t::rs2(), fimap & REG_RS2,
+ offs_rs2, subo_rs2); }
+ reg_spec_t _rs3() { return _remap(insn_t::rs3(), fimap & REG_RS3,
+ offs_rs3, subo_rs3); }
+ reg_spec_t _rvc_rs1 () { return _remap(insn_t::rvc_rs1(),
+ fimap & REG_RVC_RS1,
+ offs_rs1, subo_rs1); }
+ reg_spec_t _rvc_rs1s() { return _remap(insn_t::rvc_rs1s(),
+ fimap & REG_RVC_RS1S,
+ offs_rs1, subo_rs1); }
+ reg_spec_t _rvc_rs2 () { return _remap(insn_t::rvc_rs2(),
+ fimap & REG_RVC_RS2,
+ offs_rs2, subo_rs2); }
+ reg_spec_t _rvc_rs2s() { return _remap(insn_t::rvc_rs2s(),
+ fimap & REG_RVC_RS2S,
+ offs_rs2, subo_rs2); }
reg_spec_t _rvc_sp (bool use_offs=true)
{ return _remap(2, true, // sp always 2, always int
- use_offs ? offs_sp : NULL); }
+ use_offs ? offs_sp : NULL,
+ use_offs ? subo_sp : NULL); }
void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
reg_t *target_reg, bool zeroing, bool inv);
// 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.
- reg_spec_t _remap(uint64_t reg, bool isint, int *offs)
+ reg_spec_t _remap(uint64_t reg, bool isint, int *offs, int *subo)
{
if (sv_check_reg(isint, reg))
{
vloop_continue = true;
}
- return remap(reg, isint, offs);
+ return remap(reg, isint, offs, subo);
}
uint64_t get_saved_branch_addr() { return save_branch_addr; }
// remaps the register through the lookup table.
// will need to take the current loop index/offset somehow
- reg_spec_t remap(uint64_t reg, bool isint, int *offs);
+ reg_spec_t remap(uint64_t reg, bool isint, int *offs, int *subo);
reg_spec_t predicated(reg_spec_t const& reg, uint64_t pred);
};