mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[CRT] Implement __ftoul2_legacy
This is used by CL v19.41+. It replicates the behavior of the inline assembly code that previous CL versions generated. According to tests it works the same as with previous VS versions.
This commit is contained in:
parent
6fd6e9c306
commit
f637e6b809
1 changed files with 60 additions and 6 deletions
|
@ -1,10 +1,8 @@
|
|||
/*
|
||||
* 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:
|
||||
*
|
||||
* 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>
|
||||
|
@ -12,6 +10,7 @@
|
|||
EXTERN __ftol:PROC
|
||||
PUBLIC __ftol2
|
||||
PUBLIC __ftol2_sse
|
||||
PUBLIC __ftoul2_legacy
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
.code
|
||||
|
@ -25,4 +24,59 @@ __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
|
||||
|
|
Loading…
Reference in a new issue