From: Luke Kenneth Casson Leighton Date: Tue, 6 Nov 2018 11:18:43 +0000 (+0000) Subject: break int op down into prepare, do, and finish X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=88a4eee8fbc07e8d182de72d4ce07843ed5bedc6;p=riscv-isa-sim.git break int op down into prepare, do, and finish --- diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index 0664f58..12ae220 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -130,7 +130,7 @@ unsigned int sv_proc_t::remap(reg_spec_t const& spec) // the map is still calculated even for the 1D case // because it's a linear map unsigned int res = (unsigned int)shape->map[offs] + shape->offs; - fprintf(stderr, "remap %d %d -> %d\n", + fprintf(stderr, "remap %ld %d -> %d\n", spec.reg, offs, res); return res; } @@ -429,17 +429,14 @@ sv_reg_t (sv_proc_t::zext32)(sv_reg_t const& v) return sv_reg_t(x); } -sv_reg_t sv_proc_t::rv_add(sv_reg_t const & lhs, sv_reg_t const & rhs) +bool sv_proc_t::rv_int_op_prepare(sv_reg_t const & lhs, sv_reg_t const & rhs, + uint64_t &vlhs, uint64_t &vrhs, + uint8_t &bitwidth) { - uint8_t bitwidth = _insn->src_bitwidth; + bitwidth = _insn->src_bitwidth; if (bitwidth == xlen) { - fprintf(stderr, "add result %lx %lx %lx\n", - (uint64_t)lhs, (uint64_t)rhs, (uint64_t)(lhs + rhs)); - return lhs + rhs; + return true; } - uint64_t vlhs = 0; - uint64_t vrhs = 0; - uint64_t result = 0; // sign-extend or zero-extend to max bitwidth of lhs and rhs? // has the effect of truncating, as well. if (_insn->signextended) { // sign-extend? @@ -449,21 +446,47 @@ sv_reg_t sv_proc_t::rv_add(sv_reg_t const & lhs, sv_reg_t const & rhs) vlhs = zext_bwid(lhs, bitwidth); vrhs = zext_bwid(rhs, bitwidth); } - result = vlhs + vrhs; + return false; +} + +sv_reg_t sv_proc_t::rv_int_op_finish(sv_reg_t const & lhs, sv_reg_t const & rhs, + uint64_t &result, uint8_t &bitwidth) +{ if (_insn->signextended) { // sign-extend? result = sext_bwid(result, bitwidth); } else { // nope: zero-extend. result = zext_bwid(result, bitwidth); } uint8_t reswidth = maxelwidth(lhs.get_elwidth(), rhs.get_elwidth()); - fprintf(stderr, "add result sext %d wid %d %lx\n", _insn->signextended, + fprintf(stderr, "result sext %d wid %d %lx\n", _insn->signextended, reswidth, result); - return sv_reg_t(result, xlen, reswidth); // XXX TODO: bitwidth + return sv_reg_t(result, xlen, reswidth); +} + +sv_reg_t sv_proc_t::rv_add(sv_reg_t const & lhs, sv_reg_t const & rhs) +{ + uint8_t bitwidth = _insn->src_bitwidth; + uint64_t vlhs = 0; + uint64_t vrhs = 0; + if (rv_int_op_prepare(lhs, rhs, vlhs, vrhs, bitwidth)) { + fprintf(stderr, "add result %lx %lx %lx\n", + (uint64_t)lhs, (uint64_t)rhs, (uint64_t)(lhs + rhs)); + return lhs + rhs; + } + uint64_t result = vlhs + vrhs; + return rv_int_op_finish(lhs, rhs, result, bitwidth); } sv_reg_t sv_proc_t::rv_sub(sv_reg_t const & lhs, sv_reg_t const & rhs) { - return lhs - rhs; + uint8_t bitwidth = _insn->src_bitwidth; + uint64_t vlhs = 0; + uint64_t vrhs = 0; + if (rv_int_op_prepare(lhs, rhs, vlhs, vrhs, bitwidth)) { + return lhs - rhs; + } + uint64_t result = vlhs - vrhs; + return rv_int_op_finish(lhs, rhs, result, bitwidth); } sv_sreg_t sv_proc_t::rv_div(sv_sreg_t const & lhs, sv_sreg_t const & rhs) diff --git a/riscv/sv_insn_redirect.h b/riscv/sv_insn_redirect.h index 9f77b17..5f6bf6f 100644 --- a/riscv/sv_insn_redirect.h +++ b/riscv/sv_insn_redirect.h @@ -262,6 +262,12 @@ public: unsigned int remap(reg_spec_t const& regspec); + bool rv_int_op_prepare(sv_reg_t const & lhs, sv_reg_t const & rhs, + uint64_t &vlhs, uint64_t &vrhs, + uint8_t &bitwidth); + sv_reg_t rv_int_op_finish(sv_reg_t const & lhs, sv_reg_t const & rhs, + uint64_t &result, uint8_t &bitwidth); + #include "sv_insn_decl.h" };