[CRT] Implement portable + amd64 asm version of fabs/fabsf

Note: older versions of ML64 are broken and don't understand the register form of movq.
See https://stackoverflow.com/questions/24789339/move-quadword-between-xmm-and-general-purpose-register-in-ml64
This commit is contained in:
Timo Kreuzer 2021-05-29 19:40:30 +02:00
parent 8a67170616
commit b85afdfd25
7 changed files with 149 additions and 48 deletions

View file

@ -20,7 +20,7 @@ static TESTENTRY_DBL s_fabs_tests[] =
{
/* Special values */
{ 0x7FF0000000000000ull /* INF */, 0x7FF0000000000000ull /* INF */ },
#ifdef _M_AMD64
#ifndef _M_IX86
{ 0x7FF0000000000001ull /* NAN(SNAN) */, 0x7FF0000000000001ull /* NAN(SNAN) */ },
{ 0x7FF7FFFFFFFFFFFFull /* NAN(SNAN) */, 0x7FF7FFFFFFFFFFFFull /* NAN(SNAN) */ },
#else
@ -31,7 +31,7 @@ static TESTENTRY_DBL s_fabs_tests[] =
{ 0x7FF8000000000001ull /* NAN */, 0x7FF8000000000001ull /* NAN */ },
{ 0x7FFFFFFFFFFFFFFFull /* NAN */, 0x7FFFFFFFFFFFFFFFull /* NAN */ },
{ 0xFFF0000000000000ull /* -INF */, 0x7FF0000000000000ull /* INF */ },
#ifdef _M_AMD64
#ifndef _M_IX86
{ 0xFFF0000000000001ull /* -NAN(SNAN) */, 0xFFF0000000000001ull /* NAN(SNAN) */ },
{ 0xFFF7FFFFFFFFFFFFull /* -NAN(SNAN) */, 0xFFF7FFFFFFFFFFFFull /* NAN(SNAN) */ },
#else

View file

@ -1,9 +1,8 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of fabs
* FILE: lib/sdk/crt/math/amd64/fabs.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
* PROJECT: ReactOS CRT library
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: x64 asm implementation of fabs
* COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer@reactos.org>
*/
/* INCLUDES ******************************************************************/
@ -14,18 +13,42 @@
.code64
#ifdef _USE_ML
/* fabs is now allowed as label name, so create _fabs instead and alias fabs to it */
/* fabs is not allowed as label name, so create _fabs instead and alias fabs to it */
ALIAS <fabs> = <_fabs>
PUBLIC _fabs
_fabs:
#else
PUBLIC fabs
fabs:
#endif
UNIMPLEMENTED fabs
ret
#ifdef _USE_ML
ALIAS <fabs> = <_fabs>
/* Copy parameter into rcx */
#if !defined(_MSC_VER) || (_MSC_VER >= 1916)
movq rcx, xmm0
#else
/* Old ML64 version does not understand this form of movq and uses movd instead */
movd rcx, xmm0
#endif
/* Copy into rax */
mov rax, rcx
/* Clear sign bit in rax */
btr rax, 63
/* Check for NAN */
mov r8, HEX(7FF0000000000000)
cmp rax, r8
/* If it is NAN, copy original value back to rax */
cmova rax, rcx
#if !defined(_MSC_VER) || (_MSC_VER >= 1916)
movq xmm0, rax
#else
/* Old ML64 version does not understand this form of movq and uses movd instead */
movd xmm0, rax
#endif
ret
END

View file

@ -0,0 +1,49 @@
/*
* PROJECT: ReactOS CRT library
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: x64 asm implementation of fabsf
* COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer@reactos.org>
*/
/* INCLUDES ******************************************************************/
#include <asm.inc>
/* CODE **********************************************************************/
.code64
PUBLIC fabsf
fabsf:
/* Copy parameter into rcx */
#if !defined(_MSC_VER) || (_MSC_VER >= 1916)
movq rcx, xmm0
#else
/* Old ML64 version does not understand this form of movq and uses movd instead */
movd rcx, xmm0
#endif
/* Copy into eax */
mov eax, ecx
/* Clear sign bit in eax */
btr eax, 31
/* Set error bit in rcx */
bts ecx, 22
/* Check for NAN */
cmp eax, HEX(7F800000)
/* If eax is NAN, copy error result to rax */
cmova eax, ecx
#if !defined(_MSC_VER) || (_MSC_VER >= 1916)
movq xmm0, rax
#else
/* Old ML64 version does not understand this form of movq and uses movd instead */
movd xmm0, rax
#endif
ret
END

View file

@ -1,24 +0,0 @@
/*
* COPYRIGHT: BSD - See COPYING.ARM in the top level directory
* PROJECT: ReactOS CRT library
* PURPOSE: Implementation of fabs
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <kxarm.h>
/* CODE **********************************************************************/
TEXTAREA
LEAF_ENTRY fabs
__assertfail
bx lr
LEAF_END fabs
END
/* EOF */

38
sdk/lib/crt/math/fabs.c Normal file
View file

@ -0,0 +1,38 @@
/*
* PROJECT: ReactOS CRT library
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: Portable implementation of fabs
* COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer@reactos.org>
*/
#include <math.h>
#ifdef _MSC_VER
#pragma function(fabs)
#endif
_Check_return_
double
__cdecl
fabs(
_In_ double x)
{
/* Load the value as uint64 */
unsigned long long u64 = *(unsigned long long*)&x;
/* Clear the sign bit */
u64 &= ~(1ULL << 63);
/* Check for NAN */
if (u64 > 0x7FF0000000000000ull)
{
#ifdef _M_IX86
/* Set error bit */
*(unsigned long long*)&x |= 0x0008000000000000ull;
#endif
return x;
}
/* Convert back to double */
return *(double*)&u64;
}

View file

@ -1,8 +1,8 @@
/*
* COPYRIGHT: BSD - See COPYING.ARM in the top level directory
* PROJECT: ReactOS CRT library
* PURPOSE: Implementation of fabsf
* PROGRAMMER: Timo Kreuzer
* PROJECT: ReactOS CRT library
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: Portable implementation of fabsf
* COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer@reactos.org>
*/
#include <math.h>
@ -13,6 +13,20 @@ __cdecl
fabsf(
_In_ float x)
{
return (float)fabs((double)x);
}
/* Load the value as uint */
unsigned int u32 = *(unsigned int*)&x;
/* Clear the sign bit */
u32 &= ~(1 << 31);
/* Check for NAN */
if (u32 > 0x7F800000)
{
/* Set error bit */
*(unsigned int*)&x |= 0x00400000;
return x;
}
/* Convert back to float */
return *(float*)&u32;
}

View file

@ -8,6 +8,8 @@ list(APPEND LIBCNTPR_MATH_SOURCE
if(ARCH STREQUAL "i386")
list(APPEND LIBCNTPR_MATH_SOURCE
math/fabs.c
math/fabsf.c
math/i386/ci.c
math/i386/cicos.c
math/i386/cilog.c
@ -31,7 +33,7 @@ if(ARCH STREQUAL "i386")
math/i386/aullshr_asm.s
math/i386/ceil_asm.s
math/i386/cos_asm.s
math/i386/fabs_asm.s
# math/i386/fabs_asm.s # FIXME
math/i386/floor_asm.s
math/i386/ftol_asm.s
math/i386/ftol2_asm.s
@ -60,6 +62,7 @@ elseif(ARCH STREQUAL "amd64")
math/amd64/ceil.S
math/amd64/exp.S
math/amd64/fabs.S
math/amd64/fabsf.S
math/amd64/floor.S
math/amd64/floorf.S
math/amd64/fmod.S
@ -73,6 +76,8 @@ elseif(ARCH STREQUAL "amd64")
elseif(ARCH STREQUAL "arm")
list(APPEND LIBCNTPR_MATH_SOURCE
math/cos.c
math/fabs.c
math/fabsf.c
math/floorf.c
math/sin.c
math/sqrt.c
@ -92,15 +97,11 @@ elseif(ARCH STREQUAL "arm")
math/arm/__u64tos.c
math/arm/__64tof.h
)
list(APPEND CRT_MATH_SOURCE
math/fabsf.c
)
list(APPEND LIBCNTPR_MATH_ASM_SOURCE
math/arm/atan.s
math/arm/atan2.s
math/arm/ceil.s
math/arm/exp.s
math/arm/fabs.s
math/arm/fmod.s
math/arm/floor.s
math/arm/ldexp.s