From: Luke Kenneth Casson Leighton Date: Tue, 9 Oct 2018 14:51:12 +0000 (+0100) Subject: start adding explicit twin-predicated branch identification (rs2) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6cc8366fad0eb275ba139e12a87cd847c840fb46;p=riscv-isa-sim.git start adding explicit twin-predicated branch identification (rs2) --- diff --git a/id_regs.py b/id_regs.py index 4dbf3b5..e7a434b 100644 --- a/id_regs.py +++ b/id_regs.py @@ -62,7 +62,7 @@ drlookup = { 'rd': 0, 'frd': 0, 'rs1': 1, 'rs2': 2, 'rs3': 3, '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', @@ -176,11 +176,13 @@ if __name__ == '__main__': 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" @@ -214,5 +216,6 @@ if __name__ == '__main__': 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) diff --git a/riscv/insn_template_sv.cc b/riscv/insn_template_sv.cc index 9edce51..d2f3500 100644 --- a/riscv/insn_template_sv.cc +++ b/riscv/insn_template_sv.cc @@ -3,10 +3,10 @@ #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) @@ -37,6 +37,10 @@ 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; @@ -52,6 +56,10 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc) #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); diff --git a/riscv/sv.cc b/riscv/sv.cc index a5bae31..edb6f8b 100644 --- a/riscv/sv.cc +++ b/riscv/sv.cc @@ -204,7 +204,8 @@ uint64_t sv_insn_t::rd_bitset(uint64_t bit, bool set) 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) { diff --git a/riscv/sv_decode.h b/riscv/sv_decode.h index d72444f..92ed795 100644 --- a/riscv/sv_decode.h +++ b/riscv/sv_decode.h @@ -58,7 +58,8 @@ public: 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);