From 0f458e7027eb111250fa16028c23f4f9d01885dd Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 17 Nov 2018 05:35:37 +0000 Subject: [PATCH] add element-offset mode on LD/ST when isvec=false on address --- riscv/sv.cc | 8 ++++++- riscv/sv_insn_redirect.cc | 46 +++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/riscv/sv.cc b/riscv/sv.cc index 016fbd8..25f9e54 100644 --- a/riscv/sv.cc +++ b/riscv/sv.cc @@ -119,10 +119,14 @@ bool sv_insn_t::sv_check_reg(bool intreg, uint64_t reg) } if (r->active && r->isvec) { - fprintf(stderr, "checkreg: %ld active\n", reg); + fprintf(stderr, "checkreg: %ld active isvec\n", reg); at_least_one_reg_vectorised = true; return true; } + if (r->active) + { + fprintf(stderr, "checkreg: %ld active !vec\n", reg); + } return false; } @@ -167,10 +171,12 @@ reg_spec_t sv_insn_t::remap(uint64_t reg, bool intreg, int *voffs) // now we determine if this is a scalar/vector: if it's scalar // we return the re-mapped register... +#if 0 if (!r->isvec) // scalar { return spec; } +#endif vloop_continue = true; // aaand now, as it's a "vector", FINALLY we can pass the loop-offset diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index 640d874..5744f03 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -166,7 +166,9 @@ void (sv_proc_t::DO_WRITE_FREG)(reg_spec_t const& spec, sv_freg_t const& value) offs = remap(spec); shift = offs % nbytes; offs /= nbytes; - reg += offs; + if (spec.isvec) { + reg += offs; + } fprintf(stderr, "writefreg spec %ld bitwidth %d offs %d shift %d\n", reg, bitwidth, offs, shift); } @@ -218,7 +220,9 @@ void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value) offs = remap(spec); shift = offs % nbytes; offs /= nbytes; - reg += offs; + if (spec.isvec) { + reg += offs; + } fprintf(stderr, "writereg spec %ld %lx bitwidth %d offs %d shift %d\n", reg, wval, bitwidth, offs, shift); } @@ -278,7 +282,9 @@ freg_t (sv_proc_t::READ_FREG)(reg_spec_t const& spec) offs = remap(spec); shift = offs % nbytes; offs /= nbytes; - reg += offs; + if (spec.isvec) { + reg += offs; + } } if (((int)reg) >= SV_NFPR) { throw trap_illegal_instruction(0); @@ -313,16 +319,19 @@ reg_t sv_proc_t::READ_REG(reg_spec_t const& spec, reg_t reg = spec.reg; int bitwidth = get_bitwidth(_insn->reg_elwidth(reg, true), xlen); int shift = 0; + int origoffs = 0; int offs = 0; if (spec.offset != NULL) { int nbytes = width / bitwidth; if (nbytes == 0) { nbytes = 1; } - offs = remap(spec); - shift = offs % nbytes; - offs /= nbytes; - reg += offs; + origoffs = remap(spec); + shift = origoffs % nbytes; + offs = origoffs / nbytes; + if (spec.isvec) { + reg += offs; + } } if (((int)reg) >= SV_NFPR) { throw trap_illegal_instruction(0); @@ -332,10 +341,15 @@ reg_t sv_proc_t::READ_REG(reg_spec_t const& spec, if (addr_mode) { // offset data to load by the number of BYTES not bits - ndata = data + (bitwidth * shift / 8); - fprintf(stderr, "readreg ADDRmode %ld %ld bitwidth %d offs %d " \ + if (spec.isvec) { + ndata = data + (bitwidth * shift / 8); + } else { + ndata = data + (bitwidth * origoffs / 8); + } + fprintf(stderr, "readreg ADDRmode %p %ld %ld bw %d offs (%d) %d " \ "shift %d %lx->%lx\n", - spec.reg, reg, bitwidth, offs, shift, data, ndata); + spec.offset, spec.reg, reg, bitwidth, + origoffs, offs, shift, data, ndata); } else { @@ -1191,15 +1205,19 @@ sv_reg_t sv_proc_t::mmu_load(reg_spec_t const& spec, sv_reg_t const& offs, // addr_mode doesn't truncate the register to elwidth-specified // bitsize, it adds a modulo-offset based on the current VL loop index reg_t reg = READ_REG(spec, true, width); - sv_reg_t addr = sv_reg_t((uint64_t)reg + (int64_t)offs); + uint64_t regoffs = 0; + //if (spec.offset && !spec.isvec) { + // regoffs = *spec.offset; + //} + sv_reg_t addr = sv_reg_t((uint64_t)reg + (uint64_t)regoffs + (int64_t)offs); sv_reg_t v(0); // now that the address has been moved on by the modulo-offset, // get only an elwidth-sized element (if not "default") uint8_t rwidth = _insn->reg_elwidth(spec.reg, true); width = get_bitwidth(rwidth, width); - fprintf(stderr, "mmu_load wid %ld addr %lx offs %lx\n", - width, (uint64_t)reg, (int64_t)offs); + fprintf(stderr, "mmu_load wid %ld reg %lx regoffs %lx offs %lx\n", + width, (uint64_t)reg, regoffs, (int64_t)offs); switch (width) { case 8: @@ -1219,7 +1237,7 @@ sv_reg_t sv_proc_t::mmu_load(reg_spec_t const& spec, sv_reg_t const& offs, else v = p->get_mmu()->load_int64(addr); break; } - fprintf(stderr, "mmu_load wid %ld addr %lx offs %lx loaded %lx\n", + fprintf(stderr, "mmu_load wid %ld reg %lx offs %lx loaded %lx\n", width, (uint64_t)reg, (int64_t)offs, (uint64_t)v); v.set_elwidth(rwidth); v.set_xlen(xlen); -- 2.30.2