#define sext_xlen(x) (((sreg_t)(x) << (64-xlen)) >> (64-xlen))
#define zext_xlen(x) (((reg_t)(x) << (64-xlen)) >> (64-xlen))
-#define set_pc(x) \
+#define _set_pc(x) \
do { p->check_pc_alignment(x); \
npc = sext_xlen(x); \
} while(0)
+#ifndef SPIKE_SIMPLEV
+ #define set_pc _set_pc
+#endif
+
#define set_pc_and_serialize(x) \
do { reg_t __npc = (x) & p->pc_alignment_mask(); \
npc = PC_SERIALIZE_AFTER; \
#define xstr(s) str(s)
#define str(s) #s
+#ifdef USING_NOREGS
+ #define set_pc _set_pc
+#else
+ #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs);
+#endif
+
reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
{
int xlen = ISASZ;
if (r->active && r->isvec)
{
fprintf(stderr, "checkreg: %ld active\n", reg);
+ at_least_one_reg_vectorised = true;
return true;
}
return false;
WRITE_REG(reg, val);
return val;
}
+
+void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs)
+{
+ if (vlen == 1 or not at_least_one_reg_vectorised)
+ {
+ _set_pc(addr);
+ return;
+ }
+ rd_bitset(offs, true);
+}
+
uint64_t &p_rd, uint64_t &p_rs1, uint64_t &p_rs2, uint64_t &p_rs3,
uint64_t *p_im,
int *o_rd, int *o_rs1, int *o_rs2, int *o_rs3, int *o_imm) :
- insn_t(bits), p(pr), vloop_continue(false), fimap(f),
+ insn_t(bits), p(pr), vloop_continue(false),
+ at_least_one_reg_vectorised(false), fimap(f),
offs_rd(o_rd), offs_rs1(o_rs1), offs_rs2(o_rs2), offs_rs3(o_rs3),
offs_imm(o_imm),
prd(p_rd), prs1(p_rs1), prs2(p_rs2), prs3(p_rs3) {}
uint64_t _rvc_rs2s() { return _remap(insn_t::rvc_rs2s(), fimap & REG_RVC_RS2S,
offs_rs2); }
+ void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs);
+
// used for predicated branches. sets bit N if val=true; clears bit N if false
uint64_t rd_bitset(uint64_t bit, bool val);
private:
bool vloop_continue;
+ bool at_least_one_reg_vectorised;
unsigned int fimap;
int *offs_rd;
int *offs_rs1;