On 2020/3/29 0:13, LIU Zhiwei wrote: > > > On 2020/3/28 23:47, Richard Henderson wrote: >> On 3/28/20 8:17 AM, LIU Zhiwei wrote: >>>> Missed the improvement here.  See tcg_gen_mulsu2_i64. >>> Though I have not gotten the principle, the code in >>> tcg_gen_mulsu2_i64 is much >>> tidier. >> Let A = signed operand, >>      B = unsigned operand >>      P = unsigned product >> >> If the sign bit A is set, then P is too large. >> In that case we subtract 2**64 * B to fix that: >> >>      HI_P -= (A < 0 ? B : 0) >> >> where the conditional is computed as (A >> 63) & B. > > I think I get it. > > LET  A = 2 ** 64  - X > > THEN > > X = 2 ** 64 - A > SIGNED_P = -X * B > > if (A * B == P) then > > (2 ** 64  - X) * B == P > 2 **64 * B - X * B == P > > -X *B == P - 2**64*B > > HI_P -= (A < 0 ? B :0) > It's confusing here. I paste the clearer code. /* * Let A = signed operand, * B = unsigned operand * P = mulu64(A, B), unsigned product * * LET X = 2 ** 64 - A, 2's complement of A * SP = signed product * THEN * IF A < 0 * SP = -X * B * = -(2 ** 64 - A) * B * = A * B - 2 ** 64 * B * = P - 2 ** 64 * B * ELSE * SP = P * THEN * HI_P -= (A < 0 ? B : 0) */ static int64_t do_mulhsu_d(int64_t s2, uint64_t s1) { uint64_t hi_64, lo_64; mulu64(&lo_64, &hi_64, s2, s1); hi_64 -= s2 < 0 ? s1 : 0; return hi_64; } Zhiwei > Zhiwei >> >> r~ >