Module: wine Branch: master Commit: 04117dc8d44dde789d64f717c5d293a81316ad3d URL: https://source.winehq.org/git/wine.git/?a=commit;h=04117dc8d44dde789d64f717c... Author: Jacek Caban <jacek(a)codeweavers.com> Date: Mon Jun 8 18:12:37 2020 +0200 ntdll: Reimplement _allmul using 32-bit arithmetic. Based on compiler-rt. Signed-off-by: Jacek Caban <jacek(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ntdll/large_int.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/large_int.c b/dlls/ntdll/large_int.c index 7114b8c2d9..cf8a3df093 100644 --- a/dlls/ntdll/large_int.c +++ b/dlls/ntdll/large_int.c @@ -759,7 +759,29 @@ LONGLONG WINAPI _alldiv( LONGLONG a, LONGLONG b ) */ LONGLONG WINAPI _allmul( LONGLONG a, LONGLONG b ) { - return a * b; + LARGE_INTEGER x = { .QuadPart = a }; + LARGE_INTEGER y = { .QuadPart = b }; + LARGE_INTEGER r; + unsigned int t; + + const int bits_in_word_2 = 16; + const unsigned int lower_mask = ~0u >> bits_in_word_2; + + r.u.LowPart = (x.u.LowPart & lower_mask) * (y.u.LowPart & lower_mask); + t = r.u.LowPart >> bits_in_word_2; + r.u.LowPart &= lower_mask; + t += (x.u.LowPart >> bits_in_word_2) * (y.u.LowPart & lower_mask); + r.u.LowPart += (t & lower_mask) << bits_in_word_2; + r.u.HighPart = t >> bits_in_word_2; + t = r.u.LowPart >> bits_in_word_2; + r.u.LowPart &= lower_mask; + t += (y.u.LowPart >> bits_in_word_2) * (x.u.LowPart & lower_mask); + r.u.LowPart += (t & lower_mask) << bits_in_word_2; + r.u.HighPart += t >> bits_in_word_2; + r.u.HighPart += (x.u.LowPart >> bits_in_word_2) * (y.u.LowPart >> bits_in_word_2); + + r.u.HighPart += x.u.HighPart * y.u.LowPart + x.u.LowPart * y.u.HighPart; + return r.QuadPart; }