mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
f80d978fc0
__ftol2 is exported from msvcrt on NT6+, not from ntdll for some reason. So native apps still need to statically link _ftol2 and _ftoul2_legacy, but apps linking to msvcrt only need to statically link _ftoul2_legacy (via msvcrtex), when on NT6+.
71 lines
2.1 KiB
ArmAsm
71 lines
2.1 KiB
ArmAsm
/*
|
|
* PROJECT: ReactOS CRT
|
|
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
|
* PURPOSE: Floating point conversion routines
|
|
* COPYRIGHT: Copyright 2024 Timo Kreuzer <timo.kreuzer@reactos.org>
|
|
*/
|
|
|
|
#include <asm.inc>
|
|
|
|
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
|