ReactOS  0.4.15-dev-3299-gbe8e5fc
_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 
11 unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask)
12 {
13  return _control87(newval, mask & ~_EM_DENORMAL);
14 }
15 
16 unsigned 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 
55  switch (flags & (_RC_UP | _RC_DOWN))
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 
71 int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask)
72 {
73  unsigned int val;
74 
75  if (!MSVCRT_CHECK_PMT( !(newval & mask & ~(_MCW_EM | _MCW_RC | _MCW_DN)) ))
76  {
77  if (cur) *cur = _controlfp(0, 0); /* retrieve it anyway */
78  return EINVAL;
79  }
80  val = _controlfp(newval, mask);
81  if (cur) *cur = val;
82  return 0;
83 }
#define ARM_CW_UM
Definition: fpscr.h:14
#define _EM_DENORMAL
Definition: float.h:48
Definition: arc.h:39
#define ARM_CW_PM
Definition: fpscr.h:15
#define ARM_CW_DM
Definition: fpscr.h:16
#define _EM_INVALID
Definition: float.h:47
#define _MCW_EM
Definition: float.h:40
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define _EM_ZERODIVIDE
Definition: float.h:49
GLenum GLint GLuint mask
Definition: glext.h:6028
struct _ARM_FPSCR::@4045 data
#define ARM_CW_RC_DOWN
Definition: fpscr.h:20
switch(r->id)
Definition: btrfs.c:2980
GLuint GLfloat * val
Definition: glext.h:7180
#define _RC_NEAR
Definition: float.h:58
unsigned int __getfp(void)
#define _RC_UP
Definition: float.h:56
#define TRACE(s)
Definition: solgame.cpp:4
#define _MCW_DN
Definition: float.h:44
#define ARM_CW_RC_UP
Definition: fpscr.h:19
GLbitfield flags
Definition: glext.h:7161
#define MSVCRT_CHECK_PMT(x)
Definition: mbstowcs_s.c:26
unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask)
Definition: _controlfp.c:11
#define _EM_INEXACT
Definition: float.h:52
#define ARM_CW_RC_ZERO
Definition: fpscr.h:21
#define _MCW_RC
Definition: float.h:42
FxCollectionEntry * cur
#define ARM_CW_IM
Definition: fpscr.h:11
#define CDECL
Definition: compat.h:29
int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask)
Definition: _controlfp.c:71
void __setfp(unsigned int)
#define _EM_OVERFLOW
Definition: float.h:50
#define _RC_DOWN
Definition: float.h:57
#define _EM_UNDERFLOW
Definition: float.h:51
unsigned int CDECL _control87(unsigned int newval, unsigned int mask)
Definition: _controlfp.c:16
#define ARM_CW_OM
Definition: fpscr.h:13
unsigned int raw
Definition: fpscr.h:25
#define ARM_CW_ZM
Definition: fpscr.h:12
#define ARM_CW_RC_NEAREST
Definition: fpscr.h:18