From 8b428f45aa8aae8c24a077c31bf9e781d6fd0ab0 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 26 Sep 2018 16:21:19 +0100 Subject: [PATCH] cache the sv redirected register values on each loop if an emulated opcode ever calls insn.rd() or rs1-3 more than once sv_inst_t::remap would accidentally increment the loop offset before it was time to do so. therefore put in a cacheing system and clear it only at the end of each loop --- riscv/insn_template_sv.cc | 1 + riscv/sv_decode.h | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/riscv/insn_template_sv.cc b/riscv/insn_template_sv.cc index b8bad7a..de09f50 100644 --- a/riscv/insn_template_sv.cc +++ b/riscv/insn_template_sv.cc @@ -56,6 +56,7 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc) for (int voffs=0; voffs < vlen; voffs++) { #include INCLUDEFILE + insn.reset_caches(); // ready to increment offsets in next iteration } #else insn_t insn(bits); diff --git a/riscv/sv_decode.h b/riscv/sv_decode.h index 49a1678..eca0e77 100644 --- a/riscv/sv_decode.h +++ b/riscv/sv_decode.h @@ -16,14 +16,32 @@ class sv_insn_t: public insn_t public: sv_insn_t(insn_bits_t bits, unsigned int f) : insn_t(bits), fimap(f), + cached_rd(0xff), cached_rs1(0xff), + cached_rs2(0xff), cached_rs3(0xff), offs_rd(0), offs_rs1(0), offs_rs2(0), offs_rs3(0) {} - uint64_t rd () { return remap(insn_t::rd (), fimap & REG_RD , offs_rd); } - uint64_t rs1() { return remap(insn_t::rs1(), fimap & REG_RS1, offs_rs1); } - uint64_t rs2() { return remap(insn_t::rs2(), fimap & REG_RS2, offs_rs2); } - uint64_t rs3() { return remap(insn_t::rs3(), fimap & REG_RS3, offs_rs3); } + uint64_t rd () + { return _remap(insn_t::rd (), fimap & REG_RD , offs_rd , cached_rd); } + uint64_t rs1() + { return _remap(insn_t::rs1(), fimap & REG_RS1, offs_rs1, cached_rs1); } + uint64_t rs2() + { return _remap(insn_t::rs2(), fimap & REG_RS2, offs_rs2, cached_rs2); } + uint64_t rs3() + { return _remap(insn_t::rs3(), fimap & REG_RS3, offs_rs3, cached_rs3); } + + void reset_caches(void) + { + cached_rd = 0xff; + cached_rs1 = 0xff; + cached_rs2 = 0xff; + cached_rs3 = 0xff; + } private: unsigned int fimap; + uint64_t cached_rd; + uint64_t cached_rs1; + uint64_t cached_rs2; + uint64_t cached_rs3; int offs_rd; int offs_rs1; int offs_rs2; @@ -31,6 +49,18 @@ private: // remaps the register through the lookup table. // will need to take the current loop index/offset somehow uint64_t remap(uint64_t reg, bool isint, int &offs); + + // cached version of remap: if remap is called multiple times + // by an emulated instruction it would increment the loop offset + // before it's supposed to. + uint64_t _remap(uint64_t reg, bool isint, int &offs, uint64_t &cached) + { + if (cached == 0xff) + { + cached = remap(reg, isint, offs); + } + return cached; + } }; #endif -- 2.30.2