From 68f9627a24b22c06673cce110df43b2744adaa29 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 30 Sep 2018 07:07:43 +0100 Subject: [PATCH] add in predication to sv instruction execution this relies on setting the value of the destination register (and source registers) to zero. a bad hack but it will do --- riscv/insn_template_sv.cc | 11 ++++++--- riscv/sv.cc | 20 ++++++++++++++-- riscv/sv_decode.h | 50 ++++++++++++++++++++++++++------------- 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/riscv/insn_template_sv.cc b/riscv/insn_template_sv.cc index a83d7b0..97ca8cb 100644 --- a/riscv/insn_template_sv.cc +++ b/riscv/insn_template_sv.cc @@ -18,9 +18,13 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc) // need to know if register is used as float or int. // REGS_PATTERN is generated by id_regs.py (per opcode) unsigned int floatintmap = REGS_PATTERN; - reg_t predicate = 0; + reg_t predicate = ~0x0; sv_insn_t insn(p, bits, floatintmap, predicate, predicate, predicate, predicate); + bool zeroing; +#if defined(USING_REG_RD) || defined(USING_REG_FRD) + predicate = insn.predicate(s_insn.rd(), floatintmap & REG_RD, zeroing); +#endif // identify which regs have had their CSR entries set as vectorised. // really could do with a macro for-loop here... oh well... // integer ops, RD, RS1, RS2, RS3 (use sv_int_tb) @@ -42,8 +46,9 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc) #include INCLUDEFILE if (vlen > 1) { - fprintf(stderr, "reg %s %x vloop %d vlen %d stop %d\n", - xstr(INSN), INSNCODE, voffs, vlen, insn.stop_vloop()); + fprintf(stderr, "reg %s %x vloop %d vlen %d stop %d pred %lx\n", + xstr(INSN), INSNCODE, voffs, vlen, insn.stop_vloop(), + predicate & (1<isvec) // scalar { + // reg remapped even as scalar vloop_continue = false; - return reg; // ... remapped at this point... + return predicated(reg, voffs, pred); // returns x0 if pred bit false } // aaand now, as it's a "vector", FINALLY we can add on the loop-offset @@ -101,6 +102,10 @@ uint64_t sv_insn_t::remap(uint64_t reg, bool intreg, int &voffs) // and, at last, we have "parallelism" a la contiguous registers. reg += voffs; // wheww :) + // before returning, put the register through the predication wringer. + // this will return x0 if predication is false + reg = predicated(reg, voffs, pred); + // however... before returning, we increment the loop-offset for // this particular register, so that on the next loop the next // contiguous register will be used. @@ -149,3 +154,14 @@ reg_t sv_insn_t::predicate(uint64_t reg, bool intreg, bool &zeroing) } return predicate; } + +uint64_t sv_insn_t::predicated(uint64_t reg, int offs, uint64_t pred) +{ + if (pred & (1<