From: Luke Kenneth Casson Leighton Date: Tue, 6 Nov 2018 17:45:15 +0000 (+0000) Subject: add unsigned versions of rv_int_op_prepare and finish X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=83f72d4eefced3a1c20760db9c0d651634f1ab50;p=riscv-isa-sim.git add unsigned versions of rv_int_op_prepare and finish --- diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index c7872bc..7df63fc 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -449,6 +449,41 @@ bool sv_proc_t::rv_int_op_prepare(sv_reg_t const & lhs, sv_reg_t const & rhs, return false; } +bool sv_proc_t::rv_int_op_prepare(sv_sreg_t const & lhs, sv_sreg_t const & rhs, + int64_t &vlhs, int64_t &vrhs, + uint8_t &bitwidth) +{ + bitwidth = _insn->src_bitwidth; + if (bitwidth == xlen) { + return true; + } + // sign-extend or zero-extend to max bitwidth of lhs and rhs? + // has the effect of truncating, as well. + if (_insn->signextended) { // sign-extend? + vlhs = sext_bwid(lhs, bitwidth); + vrhs = sext_bwid(rhs, bitwidth); + } else { // nope: zero-extend. + vlhs = zext_bwid(lhs, bitwidth); + vrhs = zext_bwid(rhs, bitwidth); + } + return false; +} + +sv_sreg_t sv_proc_t::rv_int_op_finish(sv_sreg_t const & lhs, + sv_sreg_t const & rhs, + int64_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, "result sext %d wid %d %lx\n", _insn->signextended, + reswidth, result); + return sv_reg_t(result, xlen, reswidth); +} + 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) { @@ -491,7 +526,17 @@ sv_reg_t sv_proc_t::rv_sub(sv_reg_t const & lhs, sv_reg_t const & rhs) sv_sreg_t sv_proc_t::rv_div(sv_sreg_t const & lhs, sv_sreg_t const & rhs) { - return lhs / rhs; + uint8_t bitwidth = _insn->src_bitwidth; + int64_t vlhs = 0; + int64_t vrhs = 0; + if (rv_int_op_prepare(lhs, rhs, vlhs, vrhs, bitwidth)) { + sv_sreg_t result = lhs / rhs; + fprintf(stderr, "div result %lx %lx %lx\n", + (uint64_t)lhs, (uint64_t)rhs, (int64_t)result); + return result; + } + int64_t result = vlhs / vrhs; + return rv_int_op_finish(lhs, rhs, result, bitwidth); } sv_reg_t sv_proc_t::rv_div(sv_reg_t const & lhs, sv_reg_t const & rhs) diff --git a/riscv/sv_insn_redirect.h b/riscv/sv_insn_redirect.h index 82100c5..28659af 100644 --- a/riscv/sv_insn_redirect.h +++ b/riscv/sv_insn_redirect.h @@ -269,8 +269,13 @@ public: bool rv_int_op_prepare(sv_reg_t const & lhs, sv_reg_t const & rhs, uint64_t &vlhs, uint64_t &vrhs, uint8_t &bitwidth); + bool rv_int_op_prepare(sv_sreg_t const & lhs, sv_sreg_t const & rhs, + int64_t &vlhs, int64_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); + sv_sreg_t rv_int_op_finish(sv_sreg_t const & lhs, sv_sreg_t const & rhs, + int64_t &result, uint8_t &bitwidth); #include "sv_insn_decl.h" };