From cbbe2a102c9dd9a190f50fddc4bde4f5c441961d Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 29 Nov 2018 09:25:08 +0000 Subject: [PATCH] start to update predicated Branch to latest spec --- riscv/insn_template_sv.cc | 15 +++++++------ riscv/sv.cc | 44 ++++++++++++++++++++++++++++++--------- riscv/sv_decode.h | 2 +- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/riscv/insn_template_sv.cc b/riscv/insn_template_sv.cc index a4ebbc4..c73e3fd 100644 --- a/riscv/insn_template_sv.cc +++ b/riscv/insn_template_sv.cc @@ -13,7 +13,7 @@ #ifdef INSN_TYPE_BRANCH #define set_pc(x) insn.setpc(xlen, vlen, npc, x, \ - *dest_offs, target_reg); + *dest_offs, target_reg, zeroingtarg, invtarg); #else #define set_pc _set_pc #endif @@ -286,12 +286,15 @@ reg_t sv_proc_t::FN(processor_t* p, insn_t s_insn, reg_t pc) // ok, at the end of the loop, if the predicates are equal, // we're good to branch. use the saved address (to avoid // calculating the BRANCH_TARGET macro again) - uint64_t mask = (1<active) // only when predication is set { - fprintf(stderr, "vector branch ACTIVE\n"); - _set_pc(insn.get_saved_branch_addr()); + uint64_t mask = (1<active) + { + return ~0x0; // *REGISTER* not active: return all-1s (unconditional "on") + } + sv_pred_entry *r = get_predentry(reg, intreg); + if (!r->active) + { + return ~0x0; // *PREDICATION* not active: return all-1s (unconditional "on") + } + zeroing = r->zero; + fprintf(stderr, "predicate read %ld -> %ld\n", reg, r->regidx); + reg = r->regidx; + reg_spec_t rs = {reg, NULL}; + reg_t pred = p->s.READ_REG(rs); // macros go through processor_t state + if (r->inv) + { + return ~pred; + } + return pred; } + +// XXX WARNING: this fn does NOT invert the predicate (if r->inv return ~pred) reg_t sv_insn_t::predicate(uint64_t reg, bool intreg, bool &zeroing, bool &inv) { sv_reg_entry *pr = get_regentry(reg, intreg); @@ -230,14 +250,11 @@ reg_t sv_insn_t::predicate(uint64_t reg, bool intreg, bool &zeroing, bool &inv) return ~0x0; // *PREDICATION* not active: return all-1s (unconditional "on") } zeroing = r->zero; + inv = r->inv; fprintf(stderr, "predicate read %ld -> %ld\n", reg, r->regidx); reg = r->regidx; reg_spec_t rs = {reg, NULL}; reg_t predicate = p->s.READ_REG(rs); // macros go through processor_t state - if (r->inv) - { - return ~predicate; - } return predicate; } @@ -301,10 +318,10 @@ uint64_t sv_insn_t::rd_bitset(reg_t reg, int bit, bool set) } void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs, - reg_t *target_reg) + reg_t *target_reg, bool zeroing, bool inv) { save_branch_addr = addr; - if (not at_least_one_reg_vectorised) + if (not at_least_one_reg_vectorised) // scalar-scalar: make the branch { _set_pc(addr); return; @@ -320,11 +337,18 @@ void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs, if ((1<s.READ_REG(rs1()), p->s.READ_REG(rs2())); diff --git a/riscv/sv_decode.h b/riscv/sv_decode.h index 9a0b76e..f1d53fc 100644 --- a/riscv/sv_decode.h +++ b/riscv/sv_decode.h @@ -88,7 +88,7 @@ public: use_offs ? offs_sp : NULL); } void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs, - reg_t *target_reg); + reg_t *target_reg, bool zeroing, bool inv); // used for predicated branches. sets bit N if val=true; clears bit N if false uint64_t rd_bitset(reg_t reg, int bit, bool val); -- 2.30.2