mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[CRT/ARM] Floating point control functions implementation (#3870)
Implement controlfp, statusfp, fpreset, clearfp. CORE-17757 CORE-17604
This commit is contained in:
parent
c188821f8b
commit
554bbb6bab
13 changed files with 249 additions and 100 deletions
|
@ -77,6 +77,14 @@
|
|||
#define _FPCLASS_PINF 0x0200 /* Positive Infinity */
|
||||
#endif /* __MINGW_FPCLASS_DEFINED */
|
||||
|
||||
/* _statusfp bit flags */
|
||||
#define _SW_INEXACT 0x00000001 /* inexact (precision) */
|
||||
#define _SW_UNDERFLOW 0x00000002 /* underflow */
|
||||
#define _SW_OVERFLOW 0x00000004 /* overflow */
|
||||
#define _SW_ZERODIVIDE 0x00000008 /* zero divide */
|
||||
#define _SW_INVALID 0x00000010 /* invalid */
|
||||
#define _SW_DENORMAL 0x00080000 /* denormal status bit */
|
||||
|
||||
/* invalid subconditions (_SW_INVALID also set) */
|
||||
#define _SW_UNEMULATED 0x0040 /* unemulated instruction */
|
||||
#define _SW_SQRTNEG 0x0080 /* square root of a neg number */
|
||||
|
|
25
sdk/lib/crt/float/arm/__getfp.s
Normal file
25
sdk/lib/crt/float/arm/__getfp.s
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT library
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: ARM fpscr getter
|
||||
* COPYRIGHT: Copyright 2021 Roman Masanin <36927roma@gmail.com>
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <kxarm.h>
|
||||
|
||||
/* CODE **********************************************************************/
|
||||
|
||||
TEXTAREA
|
||||
|
||||
LEAF_ENTRY __getfp
|
||||
|
||||
VMRS R0,FPSCR
|
||||
|
||||
BX LR
|
||||
|
||||
LEAF_END __getfp
|
||||
|
||||
END
|
||||
/* EOF */
|
25
sdk/lib/crt/float/arm/__setfp.s
Normal file
25
sdk/lib/crt/float/arm/__setfp.s
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT library
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: ARM fpscr setter
|
||||
* COPYRIGHT: Copyright 2021 Roman Masanin <36927roma@gmail.com>
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <kxarm.h>
|
||||
|
||||
/* CODE **********************************************************************/
|
||||
|
||||
TEXTAREA
|
||||
|
||||
LEAF_ENTRY __setfp
|
||||
|
||||
VMSR FPSCR,R0
|
||||
|
||||
BX LR
|
||||
|
||||
LEAF_END __setfp
|
||||
|
||||
END
|
||||
/* EOF */
|
22
sdk/lib/crt/float/arm/_clearfp.c
Normal file
22
sdk/lib/crt/float/arm/_clearfp.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT library
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Implementation of _clearfp
|
||||
* COPYRIGHT: Copyright 2021 Roman Masanin <36927roma@gmail.com>
|
||||
*/
|
||||
|
||||
#include "fpscr.h"
|
||||
|
||||
unsigned int _clearfp(void)
|
||||
{
|
||||
ARM_FPSCR fpscr;
|
||||
unsigned int status;
|
||||
|
||||
fpscr.raw = __getfp();
|
||||
status = _statusfp();
|
||||
|
||||
fpscr.data.exception = fpscr.data.exception & ~ARM_CW_STATUS_MASK;
|
||||
|
||||
__setfp(fpscr.raw);
|
||||
return status;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: BSD - See COPYING.ARM in the top level directory
|
||||
* PROJECT: ReactOS CRT library
|
||||
* PURPOSE: Implementation of _clearfp
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <kxarm.h>
|
||||
|
||||
/* CODE **********************************************************************/
|
||||
|
||||
TEXTAREA
|
||||
|
||||
LEAF_ENTRY _clearfp
|
||||
|
||||
__assertfail
|
||||
bx lr
|
||||
|
||||
LEAF_END _clearfp
|
||||
|
||||
END
|
||||
/* EOF */
|
83
sdk/lib/crt/float/arm/_controlfp.c
Normal file
83
sdk/lib/crt/float/arm/_controlfp.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT library
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Implementation of _controlfp
|
||||
* COPYRIGHT: Copyright 2021 Roman Masanin <36927roma@gmail.com>
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
#include "fpscr.h"
|
||||
|
||||
unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask)
|
||||
{
|
||||
return _control87(newval, mask & ~_EM_DENORMAL);
|
||||
}
|
||||
|
||||
unsigned int CDECL _control87(unsigned int newval, unsigned int mask)
|
||||
{
|
||||
ARM_FPSCR fpscr;
|
||||
unsigned int flags = 0;
|
||||
|
||||
TRACE("(%08x, %08x): Called\n", newval, mask);
|
||||
|
||||
/* Get fp control word */
|
||||
fpscr.raw = __getfp();
|
||||
|
||||
TRACE("Control word before : %08x\n", fpscr.raw);
|
||||
|
||||
/* Convert into mask constants */
|
||||
if (!(fpscr.data.ex_control & ARM_CW_IM)) flags |= _EM_INVALID;
|
||||
if (!(fpscr.data.ex_control & ARM_CW_ZM)) flags |= _EM_ZERODIVIDE;
|
||||
if (!(fpscr.data.ex_control & ARM_CW_OM)) flags |= _EM_OVERFLOW;
|
||||
if (!(fpscr.data.ex_control & ARM_CW_UM)) flags |= _EM_UNDERFLOW;
|
||||
if (!(fpscr.data.ex_control & ARM_CW_PM)) flags |= _EM_INEXACT;
|
||||
if (!(fpscr.data.ex_control & ARM_CW_DM)) flags |= _EM_DENORMAL;
|
||||
|
||||
switch (fpscr.data.rounding_mode)
|
||||
{
|
||||
case ARM_CW_RC_ZERO: flags |= _RC_UP|_RC_DOWN; break;
|
||||
case ARM_CW_RC_UP: flags |= _RC_UP; break;
|
||||
case ARM_CW_RC_DOWN: flags |= _RC_DOWN; break;
|
||||
}
|
||||
|
||||
/* Mask with parameters */
|
||||
flags = (flags & ~mask) | (newval & mask);
|
||||
|
||||
/* Convert (masked) value back to fp word */
|
||||
fpscr.raw = 0;
|
||||
if (!(flags & _EM_INVALID)) fpscr.data.ex_control |= ARM_CW_IM;
|
||||
if (!(flags & _EM_ZERODIVIDE)) fpscr.data.ex_control |= ARM_CW_ZM;
|
||||
if (!(flags & _EM_OVERFLOW)) fpscr.data.ex_control |= ARM_CW_OM;
|
||||
if (!(flags & _EM_UNDERFLOW)) fpscr.data.ex_control |= ARM_CW_UM;
|
||||
if (!(flags & _EM_INEXACT)) fpscr.data.ex_control |= ARM_CW_PM;
|
||||
if (!(flags & _EM_DENORMAL)) fpscr.data.ex_control |= ARM_CW_DM;
|
||||
|
||||
switch (flags & (_RC_UP | _RC_DOWN))
|
||||
{
|
||||
case _RC_UP|_RC_DOWN: fpscr.data.rounding_mode = ARM_CW_RC_ZERO; break;
|
||||
case _RC_UP: fpscr.data.rounding_mode = ARM_CW_RC_UP; break;
|
||||
case _RC_DOWN: fpscr.data.rounding_mode = ARM_CW_RC_DOWN; break;
|
||||
case _RC_NEAR: fpscr.data.rounding_mode = ARM_CW_RC_NEAREST; break;
|
||||
}
|
||||
|
||||
TRACE("Control word after : %08x\n", fpscr.raw);
|
||||
|
||||
/* Put fp control word */
|
||||
__setfp(fpscr.raw);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
if (!MSVCRT_CHECK_PMT( !(newval & mask & ~(_MCW_EM | _MCW_RC | _MCW_DN)) ))
|
||||
{
|
||||
if (cur) *cur = _controlfp(0, 0); /* retrieve it anyway */
|
||||
return EINVAL;
|
||||
}
|
||||
val = _controlfp(newval, mask);
|
||||
if (cur) *cur = val;
|
||||
return 0;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: BSD - See COPYING.ARM in the top level directory
|
||||
* PROJECT: ReactOS CRT library
|
||||
* PURPOSE: Implementation of _controlfp
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <kxarm.h>
|
||||
|
||||
/* CODE **********************************************************************/
|
||||
|
||||
TEXTAREA
|
||||
|
||||
LEAF_ENTRY _controlfp
|
||||
|
||||
__assertfail
|
||||
bx lr
|
||||
|
||||
LEAF_END _controlfp
|
||||
|
||||
END
|
||||
/* EOF */
|
13
sdk/lib/crt/float/arm/_fpreset.c
Normal file
13
sdk/lib/crt/float/arm/_fpreset.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT library
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Implementation of _fpreset
|
||||
* COPYRIGHT: Copyright 2021 Roman Masanin <36927roma@gmail.com>
|
||||
*/
|
||||
|
||||
#include "fpscr.h"
|
||||
|
||||
void _fpreset(void)
|
||||
{
|
||||
__setfp(0x0);
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: BSD - See COPYING.ARM in the top level directory
|
||||
* PROJECT: ReactOS CRT library
|
||||
* PURPOSE: Implementation of _fpreset
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <kxarm.h>
|
||||
|
||||
/* CODE **********************************************************************/
|
||||
|
||||
TEXTAREA
|
||||
|
||||
LEAF_ENTRY _fpreset
|
||||
|
||||
__assertfail
|
||||
bx lr
|
||||
|
||||
LEAF_END _fpreset
|
||||
|
||||
END
|
||||
/* EOF */
|
24
sdk/lib/crt/float/arm/_statusfp.c
Normal file
24
sdk/lib/crt/float/arm/_statusfp.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT library
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Implementation of _statusfp
|
||||
* COPYRIGHT: Copyright 2021 Roman Masanin <36927roma@gmail.com>
|
||||
*/
|
||||
|
||||
#include "fpscr.h"
|
||||
|
||||
unsigned int _statusfp(void)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
ARM_FPSCR fpscr;
|
||||
|
||||
fpscr.raw = __getfp();
|
||||
|
||||
if (fpscr.data.exception & ARM_CW_IM) flags |= _SW_INVALID;
|
||||
if (fpscr.data.exception & ARM_CW_ZM) flags |= _SW_ZERODIVIDE;
|
||||
if (fpscr.data.exception & ARM_CW_OM) flags |= _SW_OVERFLOW;
|
||||
if (fpscr.data.exception & ARM_CW_UM) flags |= _SW_UNDERFLOW;
|
||||
if (fpscr.data.exception & ARM_CW_PM) flags |= _SW_INEXACT;
|
||||
if (fpscr.data.exception & ARM_CW_DM) flags |= _SW_DENORMAL;
|
||||
return flags;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: BSD - See COPYING.ARM in the top level directory
|
||||
* PROJECT: ReactOS CRT library
|
||||
* PURPOSE: Implementation of _statusfp
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <kxarm.h>
|
||||
|
||||
/* CODE **********************************************************************/
|
||||
|
||||
TEXTAREA
|
||||
|
||||
LEAF_ENTRY _statusfp
|
||||
|
||||
__assertfail
|
||||
bx lr
|
||||
|
||||
LEAF_END _statusfp
|
||||
|
||||
END
|
||||
/* EOF */
|
41
sdk/lib/crt/float/arm/fpscr.h
Normal file
41
sdk/lib/crt/float/arm/fpscr.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT library
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Headers for ARM fpcsr
|
||||
* COPYRIGHT: Copyright 2021 Roman Masanin <36927roma@gmail.com>
|
||||
*/
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#define ARM_CW_STATUS_MASK 0x9F
|
||||
#define ARM_CW_IM (1 << 0) /* Invalid operation mask */
|
||||
#define ARM_CW_ZM (1 << 1) /* Zero divide mask */
|
||||
#define ARM_CW_OM (1 << 2) /* Overflow mask */
|
||||
#define ARM_CW_UM (1 << 3) /* Underflow mask */
|
||||
#define ARM_CW_PM (1 << 4) /* Precision mask */
|
||||
#define ARM_CW_DM (1 << 7) /* Denormal operand mask */
|
||||
|
||||
#define ARM_CW_RC_NEAREST 0 /* round to nearest */
|
||||
#define ARM_CW_RC_UP 1 /* round up */
|
||||
#define ARM_CW_RC_DOWN 2 /* round down */
|
||||
#define ARM_CW_RC_ZERO 3 /* round toward zero (chop) */
|
||||
|
||||
typedef union _ARM_FPSCR
|
||||
{
|
||||
unsigned int raw;
|
||||
struct
|
||||
{
|
||||
unsigned int exception: 8;
|
||||
unsigned int ex_control: 8;
|
||||
unsigned int len: 3;
|
||||
unsigned int unused3: 1;
|
||||
unsigned int stride: 2;
|
||||
unsigned int rounding_mode: 2;
|
||||
unsigned int flush_to_zero: 1;
|
||||
unsigned int unused4: 3;
|
||||
unsigned int status_flag: 4;
|
||||
} data;
|
||||
} ARM_FPSCR;
|
||||
|
||||
void __setfp(unsigned int);
|
||||
unsigned int __getfp(void);
|
|
@ -33,10 +33,14 @@ elseif(ARCH STREQUAL "amd64")
|
|||
float/amd64/logb.S
|
||||
)
|
||||
elseif(ARCH STREQUAL "arm")
|
||||
list(APPEND CRT_FLOAT_SOURCE
|
||||
float/arm/_clearfp.c
|
||||
float/arm/_controlfp.c
|
||||
float/arm/_fpreset.c
|
||||
float/arm/_statusfp.c
|
||||
)
|
||||
list(APPEND CRT_FLOAT_ASM_SOURCE
|
||||
float/arm/_clearfp.s
|
||||
float/arm/_controlfp.s
|
||||
float/arm/_fpreset.s
|
||||
float/arm/_statusfp.s
|
||||
float/arm/__getfp.s
|
||||
float/arm/__setfp.s
|
||||
)
|
||||
endif()
|
||||
|
|
Loading…
Reference in a new issue