ReactOS 0.4.15-dev-8241-g63935f8
_controlfp.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS CRT library
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Implementation of _controlfp
5 * COPYRIGHT: Copyright 2021 Roman Masanin <36927roma@gmail.com>
6 */
7
8#include <precomp.h>
9#include "fpscr.h"
10
11unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask)
12{
13 return _control87(newval, mask & ~_EM_DENORMAL);
14}
15
16unsigned int CDECL _control87(unsigned int newval, unsigned int mask)
17{
18 ARM_FPSCR fpscr;
19 unsigned int flags = 0;
20
21 TRACE("(%08x, %08x): Called\n", newval, mask);
22
23 /* Get fp control word */
24 fpscr.raw = __getfp();
25
26 TRACE("Control word before : %08x\n", fpscr.raw);
27
28 /* Convert into mask constants */
29 if (!(fpscr.data.ex_control & ARM_CW_IM)) flags |= _EM_INVALID;
30 if (!(fpscr.data.ex_control & ARM_CW_ZM)) flags |= _EM_ZERODIVIDE;
31 if (!(fpscr.data.ex_control & ARM_CW_OM)) flags |= _EM_OVERFLOW;
32 if (!(fpscr.data.ex_control & ARM_CW_UM)) flags |= _EM_UNDERFLOW;
33 if (!(fpscr.data.ex_control & ARM_CW_PM)) flags |= _EM_INEXACT;
34 if (!(fpscr.data.ex_control & ARM_CW_DM)) flags |= _EM_DENORMAL;
35
36 switch (fpscr.data.rounding_mode)
37 {
38 case ARM_CW_RC_ZERO: flags |= _RC_UP|_RC_DOWN; break;
39 case ARM_CW_RC_UP: flags |= _RC_UP; break;
40 case ARM_CW_RC_DOWN: flags |= _RC_DOWN; break;
41 }
42
43 /* Mask with parameters */
44 flags = (flags & ~mask) | (newval & mask);
45
46 /* Convert (masked) value back to fp word */
47 fpscr.raw = 0;
48 if (!(flags & _EM_INVALID)) fpscr.data.ex_control |= ARM_CW_IM;
49 if (!(flags & _EM_ZERODIVIDE)) fpscr.data.ex_control |= ARM_CW_ZM;
50 if (!(flags & _EM_OVERFLOW)) fpscr.data.ex_control |= ARM_CW_OM;
51 if (!(flags & _EM_UNDERFLOW)) fpscr.data.ex_control |= ARM_CW_UM;
52 if (!(flags & _EM_INEXACT)) fpscr.data.ex_control |= ARM_CW_PM;
53 if (!(flags & _EM_DENORMAL)) fpscr.data.ex_control |= ARM_CW_DM;
54
56 {
57 case _RC_UP|_RC_DOWN: fpscr.data.rounding_mode = ARM_CW_RC_ZERO; break;
58 case _RC_UP: fpscr.data.rounding_mode = ARM_CW_RC_UP; break;
59 case _RC_DOWN: fpscr.data.rounding_mode = ARM_CW_RC_DOWN; break;
60 case _RC_NEAR: fpscr.data.rounding_mode = ARM_CW_RC_NEAREST; break;
61 }
62
63 TRACE("Control word after : %08x\n", fpscr.raw);
64
65 /* Put fp control word */
66 __setfp(fpscr.raw);
67
68 return flags;
69}
70
unsigned int __cdecl _controlfp(unsigned int newval, unsigned int mask)
Definition: _controlfp.c:10
#define CDECL
Definition: compat.h:29
switch(r->id)
Definition: btrfs.c:3046
#define ARM_CW_PM
Definition: fpscr.h:15
#define ARM_CW_RC_NEAREST
Definition: fpscr.h:18
#define ARM_CW_UM
Definition: fpscr.h:14
#define ARM_CW_RC_UP
Definition: fpscr.h:19
#define ARM_CW_OM
Definition: fpscr.h:13
#define ARM_CW_DM
Definition: fpscr.h:16
#define ARM_CW_IM
Definition: fpscr.h:11
void __setfp(unsigned int)
#define ARM_CW_ZM
Definition: fpscr.h:12
#define ARM_CW_RC_DOWN
Definition: fpscr.h:20
unsigned int __getfp(void)
#define ARM_CW_RC_ZERO
Definition: fpscr.h:21
GLenum GLint GLuint mask
Definition: glext.h:6028
GLbitfield flags
Definition: glext.h:7161
#define _RC_UP
Definition: float.h:56
#define _EM_UNDERFLOW
Definition: float.h:51
#define _EM_ZERODIVIDE
Definition: float.h:49
#define _EM_INEXACT
Definition: float.h:52
#define _EM_OVERFLOW
Definition: float.h:50
#define _EM_INVALID
Definition: float.h:47
#define _EM_DENORMAL
Definition: float.h:48
#define _RC_NEAR
Definition: float.h:58
#define _RC_DOWN
Definition: float.h:57
if(dx< 0)
Definition: linetemp.h:194
unsigned int __cdecl _control87(unsigned int, unsigned int)
Definition: _control87.c:16
#define TRACE(s)
Definition: solgame.cpp:4
unsigned int raw
Definition: fpscr.h:25
struct _ARM_FPSCR::@4318 data