diff --git a/sdk/lib/crt/CMakeLists.txt b/sdk/lib/crt/CMakeLists.txt index 6c38c518e56..740b9aec154 100644 --- a/sdk/lib/crt/CMakeLists.txt +++ b/sdk/lib/crt/CMakeLists.txt @@ -49,6 +49,7 @@ target_compile_definitions(user32_wsprintf PRIVATE _USER32_WSPRINTF) if(MSVC AND ARCH STREQUAL "i386") add_asm_files(ftol2_asm math/i386/ftol2_asm.s + math/i386/ftoul2_legacy_asm.s ) add_library(ftol2 ${ftol2_asm}) set_target_properties(ftol2 PROPERTIES LINKER_LANGUAGE "C") diff --git a/sdk/lib/crt/math/i386/ftol2_asm.s b/sdk/lib/crt/math/i386/ftol2_asm.s index a15a7031abc..974d6f5a468 100644 --- a/sdk/lib/crt/math/i386/ftol2_asm.s +++ b/sdk/lib/crt/math/i386/ftol2_asm.s @@ -1,8 +1,10 @@ /* - * PROJECT: ReactOS CRT - * LICENSE: MIT (https://spdx.org/licenses/MIT) - * PURPOSE: Floating point conversion routines - * COPYRIGHT: Copyright 2024 Timo Kreuzer + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Run-Time Library + * FILE: lib/sdk/crt/math/i386/ftol2_asm.s + * PROGRAMER: + * */ #include @@ -10,7 +12,6 @@ EXTERN __ftol:PROC PUBLIC __ftol2 PUBLIC __ftol2_sse -PUBLIC __ftoul2_legacy /* FUNCTIONS ***************************************************************/ .code @@ -24,59 +25,4 @@ __ftol2: __ftol2_sse: jmp __ftol -__real@43e0000000000000: - .quad HEX(43e0000000000000) - -__ftoul2_legacy: - - /* Compare the fp number, passed in st(0), against (LLONG_MAX + 1) - aka 9223372036854775808.0 (which is 0x43e0000000000000 in double format). - If it is smaller, it fits into an __int64, so we can pass it to _ftol2. - After this the original fp value has moved to st(1) */ - fld qword ptr [__real@43e0000000000000] - fcom - - /* Put the comparison result bits into ax */ - fnstsw ax - - /* Here we test the bits for c0 (0x01) and c3 (0x40). - We check the parity bit after the test. If it is set, - an even number of bits were set. - If both are 0, st(1) < st(0), i.e. our value is ok. - If both are 1, the value is NaN/Inf and we let _ftol2 handle it. */ - test ah, HEX(41) - jnp __ftoul2_legacy2 - - /* Clean up the fp stack and forward to _ftol2 */ - fstp st(0) - jmp __ftol2 - -__ftoul2_legacy2: - - /* Subtract (LLONG_MAX + 1) from the given fp value and put the result in st(1). - st(0) = 9223372036854775808.0 - st(1) = original fp value - 9223372036854775808.0 */ - fsub st(1), st(0) - - /* Compare the result to (LLONG_MAX + 1) again and pop the fp stack. - Here we check, whether c0 and c3 are both 0, indicating that st(0) > st(1), - i.e. fp - (LLONG_MAX + 1) < (LLONG_MAX + 1) */ - fcomp - fnstsw ax - test ah, HEX(41) - jnz __ftoul2_legacy3 - - /* We have established that fp - (LLONG_MAX + 1) fits into an __int64, - so pass that to _ftol2 and manually add the difference to the result */ - call __ftol2 - add edx, HEX(80000000) - ret - -__ftoul2_legacy3: - - /* The value is too large, just return the error value */ - xor eax, eax - mov edx, HEX(80000000) - ret - END diff --git a/sdk/lib/crt/math/i386/ftoul2_legacy_asm.s b/sdk/lib/crt/math/i386/ftoul2_legacy_asm.s new file mode 100644 index 00000000000..432d95435f1 --- /dev/null +++ b/sdk/lib/crt/math/i386/ftoul2_legacy_asm.s @@ -0,0 +1,71 @@ +/* + * PROJECT: ReactOS CRT + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Floating point conversion routines + * COPYRIGHT: Copyright 2024 Timo Kreuzer + */ + +#include + +EXTERN __ftol2:PROC + +/* FUNCTIONS ***************************************************************/ +.code + +__real@43e0000000000000: + .quad HEX(43e0000000000000) + +PUBLIC __ftoul2_legacy +__ftoul2_legacy: + + /* Compare the fp number, passed in st(0), against (LLONG_MAX + 1) + aka 9223372036854775808.0 (which is 0x43e0000000000000 in double format). + If it is smaller, it fits into an __int64, so we can pass it to _ftol2. + After this the original fp value has moved to st(1) */ + fld qword ptr [__real@43e0000000000000] + fcom + + /* Put the comparison result bits into ax */ + fnstsw ax + + /* Here we test the bits for c0 (0x01) and c3 (0x40). + We check the parity bit after the test. If it is set, + an even number of bits were set. + If both are 0, st(1) < st(0), i.e. our value is ok. + If both are 1, the value is NaN/Inf and we let _ftol2 handle it. */ + test ah, HEX(41) + jnp __ftoul2_legacy2 + + /* Clean up the fp stack and forward to _ftol2 */ + fstp st(0) + jmp __ftol2 + +__ftoul2_legacy2: + + /* Subtract (LLONG_MAX + 1) from the given fp value and put the result in st(1). + st(0) = 9223372036854775808.0 + st(1) = original fp value - 9223372036854775808.0 */ + fsub st(1), st(0) + + /* Compare the result to (LLONG_MAX + 1) again and pop the fp stack. + Here we check, whether c0 and c3 are both 0, indicating that st(0) > st(1), + i.e. fp - (LLONG_MAX + 1) < (LLONG_MAX + 1) */ + fcomp + fnstsw ax + test ah, HEX(41) + jnz __ftoul2_legacy3 + + /* We have established that fp - (LLONG_MAX + 1) fits into an __int64, + so pass that to _ftol2 and manually add the difference to the result */ + call __ftol2 + add edx, HEX(80000000) + ret + +__ftoul2_legacy3: + + /* The value is too large, just return the error value */ + xor eax, eax + mov edx, HEX(80000000) + ret + +END diff --git a/sdk/lib/crt/math/math.cmake b/sdk/lib/crt/math/math.cmake index 5821259646a..3a6c69995b5 100644 --- a/sdk/lib/crt/math/math.cmake +++ b/sdk/lib/crt/math/math.cmake @@ -40,6 +40,7 @@ if(ARCH STREQUAL "i386") math/i386/floor_asm.s math/i386/ftol_asm.s math/i386/ftol2_asm.s + math/i386/ftoul2_legacy_asm.s math/i386/log_asm.s math/i386/log10_asm.s math/i386/pow_asm.s diff --git a/sdk/lib/crt/msvcrtex.cmake b/sdk/lib/crt/msvcrtex.cmake index 6377cfa688b..232f7bda6bd 100644 --- a/sdk/lib/crt/msvcrtex.cmake +++ b/sdk/lib/crt/msvcrtex.cmake @@ -47,7 +47,8 @@ if(ARCH STREQUAL "i386") endif() if(MSVC AND DLL_EXPORT_VERSION LESS 0x600) list(APPEND MSVCRTEX_ASM_SOURCE - except/i386/__CxxFrameHandler3.s) + except/i386/__CxxFrameHandler3.s + math/i386/ftoul2_legacy_asm.s) list(APPEND MSVCRTEX_SOURCE except/i386/CxxHandleV8Frame.c) endif()