diff options
Diffstat (limited to 'riscv/insns/vsmul_vx.h')
-rw-r--r-- | riscv/insns/vsmul_vx.h | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/riscv/insns/vsmul_vx.h b/riscv/insns/vsmul_vx.h index c7909c7..4326d8f 100644 --- a/riscv/insns/vsmul_vx.h +++ b/riscv/insns/vsmul_vx.h @@ -1,34 +1,33 @@ // vsmul VRM xrm = P.VU.get_vround_mode(); -uint128_t int_max = (uint64_t(1) << (P.VU.vsew - 1)) - 1; -uint128_t int_min = - (1 << (P.VU.vsew - 1)); -uint128_t sign_mask = uint64_t(1) << (P.VU.vsew - 1); +int64_t int_max = (uint64_t(1) << (P.VU.vsew - 1)) - 1; +int64_t int_min = - (1 << (P.VU.vsew - 1)); +int64_t sign_mask = uint64_t(1) << (P.VU.vsew - 1); -VI_VX_ULOOP +VI_VX_LOOP ({ - uint128_t rs1_sign; - uint128_t vs2_sign; - uint128_t result_sign; + int64_t rs1_sign; + int64_t vs2_sign; + int64_t result_sign; rs1_sign = rs1 & sign_mask; vs2_sign = vs2 & sign_mask; bool overflow = rs1 == vs2 && rs1 == int_min; - uint128_t result = (uint128_t)rs1 * (uint128_t)vs2; - result &= ((uint128_t)1llu << ((sew * 2) - 2)) - 1; + int128_t result = (int128_t)rs1 * (int128_t)vs2; result_sign = (rs1_sign ^ vs2_sign) & sign_mask; + // rounding INT_ROUNDING(result, xrm, sew - 1); - // unsigned shifting + // remove guard bits result = result >> (sew - 1); - // saturation + // max saturation if (overflow) { result = int_max; P.VU.vxsat = 1; - } else { - result |= result_sign; } + vd = result; }) |