From: Luke Kenneth Casson Leighton Date: Thu, 8 Nov 2018 11:08:18 +0000 (+0000) Subject: annoyingly, have to modify rv_mulhu to take source reg width as basis X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=327721cc70ca8f32c185fe6dc0519233e09671ec;p=riscv-isa-sim.git annoyingly, have to modify rv_mulhu to take source reg width as basis --- diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index 6de7ea9..5db0afe 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -606,15 +606,19 @@ sv_sreg_t sv_proc_t::rv_mul(sv_sreg_t const & lhs, sv_sreg_t const & rhs) sv_reg_t sv_proc_t::rv_mulhu(sv_reg_t const & lhs, sv_reg_t const & rhs) { // normally the result is shuffled down by 32 bits (elwidth==default) - // however with variable bitwidth we want the top elwidth bits. - // so, get the destination bitwidth first... - reg_t reg = _insn->rd().reg; - uint8_t dest_elwidth = _insn->reg_elwidth(reg, true); - uint8_t bitwidth = get_bitwidth(dest_elwidth, xlen); - sv_reg_t m = rv_mul(lhs, rhs); - uint64_t result = (uint64_t)m; - result >>= std::min(bitwidth, (uint8_t)32); - return sv_reg_t(result, xlen, bitwidth); + // however with variable bitwidth we want the top elwidth bits, + // using the SOURCE registers to determine that width. + uint8_t bitwidth = _insn->src_bitwidth; + uint64_t vlhs = 0; + uint64_t vrhs = 0; + if (rv_int_op_prepare(lhs, rhs, vlhs, vrhs, bitwidth)) { + sv_reg_t result = (lhs * rhs) >> 32; + fprintf(stderr, "mul result %lx %lx %lx\n", + (uint64_t)lhs, (uint64_t)rhs, (uint64_t)result); + return result; + } + uint64_t result = (vlhs * vrhs) >> std::min(bitwidth, (uint8_t)32); + return rv_int_op_finish(lhs, rhs, result, bitwidth); } sv_sreg_t sv_proc_t::rv_mulhsu(sv_sreg_t const & lhs, sv_reg_t const & rhs)