'rvc_frs2': 2, 'rvc_frs2s': 2,
}
-def find_registers(fname, insn, twin_predication, immed_offset):
+def find_registers(fname, insn, twin_predication, immed_offset, is_branch):
# HACK! macro-skipping of instructions too painful
for notparallel in ['csr', 'lui', 'c_j', 'wfi', 'auipc',
'dret', 'uret', 'mret', 'sret',
regsname = os.path.join(insns_dir, regsname)
twin_predication = False
immed_offset = False
+ is_branch = False
with open(regsname, "w") as f:
txt = "\n#define INSN_%s\n" % insn.upper()
# help identify type of register
if insn in ['beq', 'bne', 'blt', 'bltu', 'bge', 'bgeu']:
txt += "#define INSN_TYPE_BRANCH\n"
+ is_branch = 'STD' # standard branch
if insn in ['lb', 'lbu', 'lw', 'lwu', 'ld', 'ldu']:
twin_predication = True
txt += "#define INSN_TYPE_LOAD\n"
txt += "#define INSN_TYPE_FP_BRANCH\n"
if twin_predication:
txt += "\n#define INSN_CATEGORY_TWINPREDICATION\n"
- txt += find_registers(fname, insn, twin_predication, immed_offset)
+ txt += find_registers(fname, insn, twin_predication,
+ immed_offset, is_branch)
f.write(txt)
#define xstr(s) str(s)
#define str(s) #s
-#ifdef USING_NOREGS
- #define set_pc _set_pc
+#ifdef INSN_TYPE_BRANCH
+ #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs, target_pred);
#else
- #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs);
+ #define set_pc _set_pc
#endif
reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
reg_t src_pred = ~0x0;
int *src_offs = &(p->get_state()->srcoffs);
bool zeroingsrc = false;
+#endif
+#ifdef INSN_TYPE_BRANCH
+ reg_t target_pred = ~0x0;
+ bool zeroingtarg = false;
#endif
sv_insn_t insn(p, bits, floatintmap, PRED_ARGS, OFFS_ARGS);
reg_t sp = 0;
#ifdef INSN_TYPE_C_STACK_ST
sp = insn._remap(X_SP, true, dest_offs);
#endif
+#ifdef INSN_TYPE_BRANCH
+ // all branch ops are rs1, rs2. take target (dest) predicate from rs2.
+ target_pred = insn.predicate(s_insn.rs2(), true, zeroingtarg);
+#endif
#ifdef INSN_CATEGORY_TWINPREDICATION
#ifdef INSN_TYPE_C_STACK_LD
src_pred = insn.predicate(sp, SRC_PREDINT, zeroingsrc);
return val;
}
-void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs)
+void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
+ uint64_t predicate)
{
if (vlen == 1 or not at_least_one_reg_vectorised)
{
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);
+ void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
+ uint64_t predicate);
// used for predicated branches. sets bit N if val=true; clears bit N if false
uint64_t rd_bitset(uint64_t bit, bool val);