On 3/17/20 8:06 AM, LIU Zhiwei wrote:
> +static int64_t vsmul64(CPURISCVState *env, int vxrm, int64_t a, int64_t b)
> +{
> + uint8_t round;
> + uint64_t hi_64, lo_64, Hi62;
> + uint8_t hi62, hi63, lo63;
> +
> + muls64(&lo_64, &hi_64, a, b);
> + hi62 = extract64(hi_64, 62, 1);
> + lo63 = extract64(lo_64, 63, 1);
> + hi63 = extract64(hi_64, 63, 1);
> + Hi62 = extract64(hi_64, 0, 62);
This seems like way more work than necessary.
> + if (hi62 != hi63) {
> + env->vxsat = 0x1;
> + return INT64_MAX;
> + }
This can only happen for a == b == INT64_MIN.
Perhaps just test exactly that and move it above the multiply?
> + round = get_round(vxrm, lo_64, 63);
> + if (round && (Hi62 == 0x3fffffff) && lo63) {
> + env->vxsat = 0x1;
> + return hi62 ? INT64_MIN : INT64_MAX;
> + } else {
> + if (lo63 && round) {
> + return (hi_64 + 1) << 1;
> + } else {
> + return (hi_64 << 1) | lo63 | round;
> + }
> + }
/* Cannot overflow, as there are always
2 sign bits after multiply. */
ret = (hi_64 << 1) | (lo_64 >> 63);
if (round) {
if (ret == INT64_MAX) {
env->vxsat = 1;
} else {
ret += 1;
}
}
return ret;
r~