From: Luke Kenneth Casson Leighton Date: Sat, 10 Nov 2018 06:59:17 +0000 (+0000) Subject: slightly different 64-bit rv_mulhu elwidth rules X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b15ade830436a456c2a55e85a72d74e350499ccb;p=riscv-isa-sim.git slightly different 64-bit rv_mulhu elwidth rules --- diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index 937b232..3ce22f3 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -451,6 +451,8 @@ bool sv_proc_t::rv_int_op_prepare(SLHSTYPE const & lhs, SRHSTYPE const & rhs, \ bitwidth = xlen; \ } \ if (bitwidth == xlen) { \ + vlhs = lhs; \ + vrhs = rhs; \ return true; \ } \ uint8_t lbitwidth = get_bitwidth(lhs.get_elwidth(), xlen); \ @@ -459,8 +461,8 @@ bool sv_proc_t::rv_int_op_prepare(SLHSTYPE const & lhs, SRHSTYPE const & rhs, \ vlhs = sext_bwid(lhs, lbitwidth); \ vrhs = sext_bwid(rhs, rbitwidth); \ } else { \ - vlhs = zext_bwid(lhs, lbitwidth); \ - vrhs = zext_bwid(rhs, rbitwidth); \ + vlhs = zext_bwid(lhs, lbitwidth); \ + vrhs = zext_bwid(rhs, rbitwidth); \ } \ return false; \ } \ @@ -558,9 +560,25 @@ OP_MULH_FN(_mulhsu, sv_sreg_t, sv_reg_t, sv_sreg_t, int64_t, uint64_t, int64_t ) OP_MULH_FN(_mulh , sv_sreg_t, sv_sreg_t, sv_sreg_t, int64_t, int64_t, int64_t ) /* 64-bit mulh/mulhu/mulhsu */ -sv_reg_t (sv_proc_t::mulhu)(sv_reg_t const& a, sv_reg_t const& b) +/* here is slightly different from other macros, because if either + src register is 64-bit it's necessary to use the 64-bit mulhu + function. then, if the result is <64bit it's truncated. + only when both source registers are <= 32 bit can we use + the 32-bit rv_mulh. + */ +sv_reg_t (sv_proc_t::mulhu)(sv_reg_t const& lhs, sv_reg_t const& rhs) { - return sv_reg_t(::mulhu(a, b)); + uint8_t bitwidth = _insn->src_bitwidth; \ + uint64_t vlhs = 0; \ + uint64_t vrhs = 0; \ + if (rv_int_op_prepare(lhs, rhs, vlhs, vrhs, bitwidth) || \ + lhs.get_elwidth() == 0 || rhs.get_elwidth() == 0 ) { \ + uint64_t result = ::mulhu(vlhs, vrhs); + fprintf(stderr, "%s result %lx %lx %lx\n", \ + "mulhu", (uint64_t)vlhs, (uint64_t)vrhs, (uint64_t)result); \ + return rv_int_op_finish(lhs, rhs, result, bitwidth); \ + } \ + return rv_mulh(lhs, rhs); } sv_sreg_t (sv_proc_t::mulhsu)(sv_sreg_t const& a, sv_reg_t const& b)