whoops, must use dest bitwidth on mulhsu
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 7 Nov 2018 17:29:43 +0000 (17:29 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 7 Nov 2018 17:29:43 +0000 (17:29 +0000)
riscv/sv_insn_redirect.cc

index bf78ba957607d7ee5e0c70d89894a853d029d35d..6de7ea92833eae82ab84f63a67a2bb6bcfe6e642 100644 (file)
@@ -605,15 +605,15 @@ sv_sreg_t sv_proc_t::rv_mul(sv_sreg_t const & lhs, sv_sreg_t const & rhs)
 /* 32-bit mulh/mulhu/mulhsu */
 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);
-    uint8_t bitwidth = get_bitwidth(m.get_elwidth(), xlen);
     uint64_t result = (uint64_t)m;
     result >>= std::min(bitwidth, (uint8_t)32);
-    if (_insn->signextended) {
-        result = sext_bwid(result, bitwidth);
-    } else {
-        result = zext_bwid(result, bitwidth);
-    }
     return sv_reg_t(result, xlen, bitwidth);
 }