ReactOS 0.4.17-dev-1321-g5c122a9
math.c File Reference
#include <assert.h>
#include <complex.h>
#include <stdio.h>
#include <fenv.h>
#include <fpieee.h>
#include <limits.h>
#include <locale.h>
#include <math.h>
#include "msvcrt.h"
#include "winternl.h"
#include "wine/asm.h"
#include "wine/debug.h"
#include <stdlib.h>
Include dependency graph for math.c:

Go to the source code of this file.

Macros

#define _DOMAIN   1 /* domain error in argument */
 
#define _SING   2 /* singularity */
 
#define _OVERFLOW   3 /* range overflow */
 
#define _UNDERFLOW   4 /* range underflow */
 
#define SET_X87_CW(MASK)
 
#define RESET_X87_CW
 

Typedefs

typedef int(CDECL * MSVCRT_matherr_func) (struct _exception *)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msvcrt)
 
void msvcrt_init_math (void *module)
 
static double ret_nan (BOOL update_sw)
 
int CDECL _matherr (struct _exception *e)
 
double math_error (int type, const char *name, double arg1, double arg2, double retval)
 
void CDECL __setusermatherr (MSVCRT_matherr_func func)
 
int CDECL _set_SSE2_enable (int flag)
 
float CDECL _chgsignf (float num)
 
int CDECL _fpclassf (float num)
 
int CDECL _finitef (float num)
 
int CDECL _isnanf (float num)
 
float CDECL MSVCRT_atanf (float x)
 
short CDECL _fdclass (float x)
 
static BOOL sqrtf_validate (float *x)
 
float CDECL MSVCRT_sqrtf (float x)
 
float CDECL MSVCRT_tanhf (float x)
 
double CDECL MSVCRT_asin (double x)
 
double CDECL MSVCRT_atan (double x)
 
double CDECL MSVCRT_exp (double x)
 
short CDECL _dclass (double x)
 
static BOOL sqrt_validate (double *x, BOOL update_sw)
 
double CDECL MSVCRT_sqrt (double x)
 
double CDECL MSVCRT_tanh (double x)
 
int CDECL _fpclass (double num)
 
unsigned int CDECL MSVCRT__rotl (unsigned int num, int shift)
 
__msvcrt_ulong CDECL MSVCRT__lrotl (__msvcrt_ulong num, int shift)
 
__msvcrt_ulong CDECL MSVCRT__lrotr (__msvcrt_ulong num, int shift)
 
unsigned int CDECL MSVCRT__rotr (unsigned int num, int shift)
 
unsigned __int64 CDECL MSVCRT__rotl64 (unsigned __int64 num, int shift)
 
unsigned __int64 CDECL MSVCRT__rotr64 (unsigned __int64 num, int shift)
 
int CDECL abs (int n)
 
__msvcrt_long CDECL labs (__msvcrt_long n)
 
__int64 CDECL _abs64 (__int64 n)
 
static void _setfp (unsigned int *cw, unsigned int cw_mask, unsigned int *sw, unsigned int sw_mask)
 
unsigned int CDECL _statusfp (void)
 
unsigned int CDECL _clearfp (void)
 
int *CDECL __fpecode (void)
 
double CDECL ldexp (double num, int exp)
 
double CDECL _cabs (struct _complex num)
 
double CDECL _chgsign (double num)
 
unsigned int CDECL _control87 (unsigned int newval, unsigned int mask)
 
unsigned int CDECL _controlfp (unsigned int newval, unsigned int mask)
 
void CDECL _set_controlfp (unsigned int newval, unsigned int mask)
 
int CDECL _controlfp_s (unsigned int *cur, unsigned int newval, unsigned int mask)
 
int CDECL _finite (double num)
 
void CDECL _fpreset (void)
 
int CDECL _isnan (double num)
 
char *CDECL _ecvt (double number, int ndigits, int *decpt, int *sign)
 
int CDECL _ecvt_s (char *buffer, size_t length, double number, int ndigits, int *decpt, int *sign)
 
char *CDECL _fcvt (double number, int ndigits, int *decpt, int *sign)
 
int CDECL _fcvt_s (char *outbuffer, size_t size, double number, int ndigits, int *decpt, int *sign)
 
char *CDECL _gcvt (double number, int ndigit, char *buff)
 
int CDECL _gcvt_s (char *buff, size_t size, double number, int digits)
 
div_t CDECL div (int num, int denom)
 
ldiv_t CDECL ldiv (__msvcrt_long num, __msvcrt_long denom)
 
double CDECL _scalb (double num, __msvcrt_long power)
 
float CDECL _scalbf (float num, __msvcrt_long power)
 

Variables

static MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL
 
BOOL sse2_supported
 
static BOOL sse2_enabled
 

Macro Definition Documentation

◆ _DOMAIN

#define _DOMAIN   1 /* domain error in argument */

Definition at line 62 of file math.c.

◆ _OVERFLOW

#define _OVERFLOW   3 /* range overflow */

Definition at line 64 of file math.c.

◆ _SING

#define _SING   2 /* singularity */

Definition at line 63 of file math.c.

◆ _UNDERFLOW

#define _UNDERFLOW   4 /* range underflow */

Definition at line 65 of file math.c.

◆ RESET_X87_CW

#define RESET_X87_CW
Value:
"movw (%esp), %ax\n\t" \
"cmpw %ax, 2(%esp)\n\t" \
"je 1f\n\t" \
"fstpl 8(%esp)\n\t" \
"fldcw (%esp)\n\t" \
"fldl 8(%esp)\n\t" \
"fwait\n\t" \
"1:\n\t" \
"addl $4, %esp\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")

Definition at line 104 of file math.c.

◆ SET_X87_CW

#define SET_X87_CW (   MASK)
Value:
"subl $4, %esp\n\t" \
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
"fnstcw (%esp)\n\t" \
"movw (%esp), %ax\n\t" \
"movw %ax, 2(%esp)\n\t" \
"testw $" #MASK ", %ax\n\t" \
"jz 1f\n\t" \
"andw $~" #MASK ", %ax\n\t" \
"movw %ax, 2(%esp)\n\t" \
"fldcw 2(%esp)\n\t" \
"1:\n\t"
ULONG MASK
Definition: afilter.h:45

Definition at line 91 of file math.c.

Typedef Documentation

◆ MSVCRT_matherr_func

typedef int(CDECL * MSVCRT_matherr_func) (struct _exception *)

Definition at line 67 of file math.c.

Function Documentation

◆ __fpecode()

int *CDECL __fpecode ( void  )

Definition at line 1214 of file math.c.

1215{
1216 return &msvcrt_get_thread_data()->fpecode;
1217}
thread_data_t *CDECL msvcrt_get_thread_data(void)
Definition: ucrt_tls_sup.c:59

◆ __setusermatherr()

void CDECL __setusermatherr ( MSVCRT_matherr_func  func)

Definition at line 159 of file math.c.

160{
162 TRACE("new matherr handler %p\n", func);
163}
static MSVCRT_matherr_func MSVCRT_default_matherr_func
Definition: math.c:69
GLenum func
Definition: glext.h:6028
#define TRACE(s)
Definition: solgame.cpp:4

◆ _abs64()

__int64 CDECL _abs64 ( __int64  n)

Definition at line 711 of file math.c.

712{
713 return n >= 0 ? n : -n;
714}
GLdouble n
Definition: glext.h:7729

◆ _cabs()

double CDECL _cabs ( struct _complex  num)

Definition at line 1238 of file math.c.

1239{
1240 return sqrt(num.x * num.x + num.y * num.y);
1241}
_ACRTIMP double __cdecl sqrt(double)
Definition: sqrt.c:5
GLuint GLuint num
Definition: glext.h:9618

◆ _chgsign()

double CDECL _chgsign ( double  num)

Definition at line 1246 of file math.c.

1247{
1248 union { double f; UINT64 i; } u = { num };
1249 u.i ^= 1ull << 63;
1250 return u.f;
1251}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define f
Definition: ke_i.h:83

◆ _chgsignf()

float CDECL _chgsignf ( float  num)

Definition at line 203 of file math.c.

204{
205 union { float f; UINT32 i; } u = { num };
206 u.i ^= 0x80000000;
207 return u.f;
208}
uint32_t UINT32
Definition: typedefs.h:59

◆ _clearfp()

unsigned int CDECL _clearfp ( void  )

Definition at line 1193 of file math.c.

1194{
1195 unsigned int flags = 0;
1196#ifdef __i386__
1197 _setfp(NULL, 0, &flags, _MCW_EM);
1198 if (sse2_supported)
1199 {
1200 unsigned int sse_sw = 0;
1201
1202 _setfp_sse(NULL, 0, &sse_sw, _MCW_EM);
1203 flags |= sse_sw;
1204 }
1205#else
1206 _setfp(NULL, 0, &flags, _MCW_EM);
1207#endif
1208 return flags;
1209}
#define NULL
Definition: types.h:112
#define _MCW_EM
Definition: float.h:64
BOOL sse2_supported
Definition: math.c:71
static void _setfp(unsigned int *cw, unsigned int cw_mask, unsigned int *sw, unsigned int sw_mask)
Definition: math.c:842
GLbitfield flags
Definition: glext.h:7161

◆ _control87()

unsigned int CDECL _control87 ( unsigned int  newval,
unsigned int  mask 
)

Definition at line 1284 of file math.c.

1285{
1286 unsigned int flags = 0;
1287#if defined(__i386__) && (_MSVCR_VER == 0 || _MSVCR_VER >= 80)
1288 unsigned int sse2_cw;
1289
1290 __control87_2( newval, mask, &flags, &sse2_cw );
1291
1292 if (sse2_supported)
1293 {
1294 if ((flags ^ sse2_cw) & (_MCW_EM | _MCW_RC)) flags |= _EM_AMBIGUOUS;
1295 flags |= sse2_cw;
1296 }
1297#else
1298 flags = newval;
1299 _setfp(&flags, mask, NULL, 0);
1300#endif
1301 return flags;
1302}
#define _MCW_RC
Definition: float.h:66
#define _EM_AMBIGUOUS
Definition: float.h:90
GLenum GLint GLuint mask
Definition: glext.h:6028

Referenced by _controlfp().

◆ _controlfp()

unsigned int CDECL _controlfp ( unsigned int  newval,
unsigned int  mask 
)

Definition at line 1307 of file math.c.

1308{
1309 return _control87( newval, mask & ~_EM_DENORMAL );
1310}
#define _EM_DENORMAL
Definition: float.h:72
unsigned int CDECL _control87(unsigned int newval, unsigned int mask)
Definition: math.c:1284

Referenced by _controlfp_s(), and _set_controlfp().

◆ _controlfp_s()

int CDECL _controlfp_s ( unsigned int *  cur,
unsigned int  newval,
unsigned int  mask 
)

Definition at line 1323 of file math.c.

1324{
1325 static const unsigned int all_flags = (_MCW_EM | _MCW_IC | _MCW_RC |
1326 _MCW_PC | _MCW_DN);
1327 unsigned int val;
1328
1329 if (!MSVCRT_CHECK_PMT( !(newval & mask & ~all_flags) ))
1330 {
1331 if (cur) *cur = _controlfp( 0, 0 ); /* retrieve it anyway */
1332 return EINVAL;
1333 }
1334 val = _controlfp( newval, mask );
1335 if (cur) *cur = val;
1336 return 0;
1337}
#define EINVAL
Definition: errno.h:44
#define _MCW_PC
Definition: float.h:67
#define _MCW_IC
Definition: float.h:65
#define _MCW_DN
Definition: float.h:68
unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask)
Definition: math.c:1307
#define MSVCRT_CHECK_PMT(x)
Definition: msvcrt.h:378
FxCollectionEntry * cur
GLuint GLfloat * val
Definition: glext.h:7180

◆ _dclass()

short CDECL _dclass ( double  x)

Referenced by sqrt_validate().

◆ _ecvt()

char *CDECL _ecvt ( double  number,
int  ndigits,
int *  decpt,
int *  sign 
)

Definition at line 1767 of file math.c.

1768{
1769 int prec, len;
1771 /* FIXME: check better for overflow (native supports over 300 chars) */
1772 ndigits = min( ndigits, 80 - 8); /* 8 : space for sign, dec point, "e",
1773 * 4 for exponent and one for
1774 * terminating '\0' */
1775 if (!data->efcvt_buffer)
1776 data->efcvt_buffer = malloc( 80 ); /* ought to be enough */
1777
1778 /* handle cases with zero ndigits or less */
1779 prec = ndigits;
1780 if( prec < 1) prec = 2;
1781 len = _snprintf(data->efcvt_buffer, 80, "%.*le", prec - 1, number);
1782
1783 if (data->efcvt_buffer[0] == '-') {
1784 memmove( data->efcvt_buffer, data->efcvt_buffer + 1, len-- );
1785 *sign = 1;
1786 } else *sign = 0;
1787
1788 /* take the decimal "point away */
1789 if( prec != 1)
1790 memmove( data->efcvt_buffer + 1, data->efcvt_buffer + 2, len - 1 );
1791 /* take the exponential "e" out */
1792 data->efcvt_buffer[ prec] = '\0';
1793 /* read the exponent */
1794 sscanf( data->efcvt_buffer + prec + 1, "%d", decpt);
1795 (*decpt)++;
1796 /* adjust for some border cases */
1797 if( data->efcvt_buffer[0] == '0')/* value is zero */
1798 *decpt = 0;
1799 /* handle cases with zero ndigits or less */
1800 if( ndigits < 1){
1801 if( data->efcvt_buffer[ 0] >= '5')
1802 (*decpt)++;
1803 data->efcvt_buffer[ 0] = '\0';
1804 }
1805 TRACE("out=\"%s\"\n",data->efcvt_buffer);
1806 return data->efcvt_buffer;
1807}
#define malloc
Definition: debug_ros.c:4
_ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl sscanf(const char *, const char *,...) __WINE_CRT_SCANF_ATTR(2
static int __cdecl _snprintf(char *buffer, size_t size, const char *format,...) __WINE_CRT_PRINTF_ATTR(3
Definition: stdio.h:507
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum GLsizei len
Definition: glext.h:6722
#define sign(x)
Definition: mapdesc.cc:613
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static unsigned int number
Definition: dsound.c:1479
static size_t double int ndigits
Definition: printf.c:52
static size_t double int int * decpt
Definition: printf.c:52
#define min(a, b)
Definition: monoChain.cc:55

◆ _ecvt_s()

int CDECL _ecvt_s ( char *  buffer,
size_t  length,
double  number,
int  ndigits,
int *  decpt,
int *  sign 
)

Definition at line 1812 of file math.c.

1813{
1814 int prec, len;
1815 char *result;
1816
1817 if (!MSVCRT_CHECK_PMT(buffer != NULL)) return EINVAL;
1818 if (!MSVCRT_CHECK_PMT(decpt != NULL)) return EINVAL;
1819 if (!MSVCRT_CHECK_PMT(sign != NULL)) return EINVAL;
1820 if (!MSVCRT_CHECK_PMT_ERR( length > 2, ERANGE )) return ERANGE;
1821 if (!MSVCRT_CHECK_PMT_ERR(ndigits < (int)length - 1, ERANGE )) return ERANGE;
1822
1823 /* handle cases with zero ndigits or less */
1824 prec = ndigits;
1825 if( prec < 1) prec = 2;
1826 result = malloc(prec + 8);
1827
1828 len = _snprintf(result, prec + 8, "%.*le", prec - 1, number);
1829 if (result[0] == '-') {
1830 memmove( result, result + 1, len-- );
1831 *sign = 1;
1832 } else *sign = 0;
1833
1834 /* take the decimal "point away */
1835 if( prec != 1)
1836 memmove( result + 1, result + 2, len - 1 );
1837 /* take the exponential "e" out */
1838 result[ prec] = '\0';
1839 /* read the exponent */
1840 sscanf( result + prec + 1, "%d", decpt);
1841 (*decpt)++;
1842 /* adjust for some border cases */
1843 if( result[0] == '0')/* value is zero */
1844 *decpt = 0;
1845 /* handle cases with zero ndigits or less */
1846 if( ndigits < 1){
1847 if( result[ 0] >= '5')
1848 (*decpt)++;
1849 result[ 0] = '\0';
1850 }
1851 memcpy( buffer, result, max(ndigits + 1, 1) );
1852 free( result );
1853 return 0;
1854}
#define free
Definition: debug_ros.c:5
#define ERANGE
Definition: errno.h:55
#define MSVCRT_CHECK_PMT_ERR(x, err)
Definition: msvcrt.h:377
GLuint buffer
Definition: glext.h:5915
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define max(a, b)
Definition: svc.c:63

◆ _fcvt()

char *CDECL _fcvt ( double  number,
int  ndigits,
int *  decpt,
int *  sign 
)

Definition at line 1859 of file math.c.

1860{
1862 int stop, dec1, dec2;
1863 char *ptr1, *ptr2, *first;
1864 char buf[80]; /* ought to be enough */
1865 char decimal_separator = get_locinfo()->lconv->decimal_point[0];
1866
1867 if (!data->efcvt_buffer)
1868 data->efcvt_buffer = malloc( 80 ); /* ought to be enough */
1869
1870 stop = _snprintf(buf, 80, "%.*f", ndigits < 0 ? 0 : ndigits, number);
1871 ptr1 = buf;
1872 ptr2 = data->efcvt_buffer;
1873 first = NULL;
1874 dec1 = 0;
1875 dec2 = 0;
1876
1877 if (*ptr1 == '-') {
1878 *sign = 1;
1879 ptr1++;
1880 } else *sign = 0;
1881
1882 /* For numbers below the requested resolution, work out where
1883 the decimal point will be rather than finding it in the string */
1884 if (number < 1.0 && number > 0.0) {
1885 dec2 = log10(number + 1e-10);
1886 if (-dec2 <= ndigits) dec2 = 0;
1887 }
1888
1889 /* If requested digits is zero or less, we will need to truncate
1890 * the returned string */
1891 if (ndigits < 1) {
1892 stop += ndigits;
1893 }
1894
1895 while (*ptr1 == '0') ptr1++; /* Skip leading zeroes */
1896 while (*ptr1 != '\0' && *ptr1 != decimal_separator) {
1897 if (!first) first = ptr2;
1898 if ((ptr1 - buf) < stop) {
1899 *ptr2++ = *ptr1++;
1900 } else {
1901 ptr1++;
1902 }
1903 dec1++;
1904 }
1905
1906 if (ndigits > 0) {
1907 ptr1++;
1908 if (!first) {
1909 while (*ptr1 == '0') { /* Process leading zeroes */
1910 *ptr2++ = *ptr1++;
1911 dec1--;
1912 }
1913 }
1914 while (*ptr1 != '\0') {
1915 if (!first) first = ptr2;
1916 *ptr2++ = *ptr1++;
1917 }
1918 }
1919
1920 *ptr2 = '\0';
1921
1922 /* We never found a non-zero digit, then our number is either
1923 * smaller than the requested precision, or 0.0 */
1924 if (!first) {
1925 if (number > 0.0) {
1926 first = ptr2;
1927 } else {
1928 first = data->efcvt_buffer;
1929 dec1 = 0;
1930 }
1931 }
1932
1933 *decpt = dec2 ? dec2 : dec1;
1934 return first;
1935}
double log10(double x)
Definition: freeldr.c:191
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
const GLint * first
Definition: glext.h:5794
#define e
Definition: ke_i.h:82
#define get_locinfo()
Definition: winesup.h:25

◆ _fcvt_s()

int CDECL _fcvt_s ( char *  outbuffer,
size_t  size,
double  number,
int  ndigits,
int *  decpt,
int *  sign 
)

Definition at line 1940 of file math.c.

1941{
1942 int stop, dec1, dec2;
1943 char *ptr1, *ptr2, *first;
1944 char buf[80]; /* ought to be enough */
1945 char decimal_separator = get_locinfo()->lconv->decimal_point[0];
1946
1947 if (!outbuffer || !decpt || !sign || size == 0)
1948 {
1949 *_errno() = EINVAL;
1950 return EINVAL;
1951 }
1952
1953 stop = _snprintf(buf, 80, "%.*f", ndigits < 0 ? 0 : ndigits, number);
1954 ptr1 = buf;
1955 ptr2 = outbuffer;
1956 first = NULL;
1957 dec1 = 0;
1958 dec2 = 0;
1959
1960 if (*ptr1 == '-') {
1961 *sign = 1;
1962 ptr1++;
1963 } else *sign = 0;
1964
1965 /* For numbers below the requested resolution, work out where
1966 the decimal point will be rather than finding it in the string */
1967 if (number < 1.0 && number > 0.0) {
1968 dec2 = log10(number + 1e-10);
1969 if (-dec2 <= ndigits) dec2 = 0;
1970 }
1971
1972 /* If requested digits is zero or less, we will need to truncate
1973 * the returned string */
1974 if (ndigits < 1) {
1975 stop += ndigits;
1976 }
1977
1978 while (*ptr1 == '0') ptr1++; /* Skip leading zeroes */
1979 while (*ptr1 != '\0' && *ptr1 != decimal_separator) {
1980 if (!first) first = ptr2;
1981 if ((ptr1 - buf) < stop) {
1982 if (size > 1) {
1983 *ptr2++ = *ptr1++;
1984 size--;
1985 }
1986 } else {
1987 ptr1++;
1988 }
1989 dec1++;
1990 }
1991
1992 if (ndigits > 0) {
1993 ptr1++;
1994 if (!first) {
1995 while (*ptr1 == '0') { /* Process leading zeroes */
1996 if (number == 0.0 && size > 1) {
1997 *ptr2++ = '0';
1998 size--;
1999 }
2000 ptr1++;
2001 dec1--;
2002 }
2003 }
2004 while (*ptr1 != '\0') {
2005 if (!first) first = ptr2;
2006 if (size > 1) {
2007 *ptr2++ = *ptr1++;
2008 size--;
2009 }
2010 }
2011 }
2012
2013 *ptr2 = '\0';
2014
2015 /* We never found a non-zero digit, then our number is either
2016 * smaller than the requested precision, or 0.0 */
2017 if (!first && (number <= 0.0))
2018 dec1 = 0;
2019
2020 *decpt = dec2 ? dec2 : dec1;
2021 return 0;
2022}
int *CDECL _errno(void)
Definition: errno.c:215
GLsizeiptr size
Definition: glext.h:5919

◆ _fdclass()

short CDECL _fdclass ( float  x)

Referenced by sqrtf_validate().

◆ _finite()

int CDECL _finite ( double  num)

Definition at line 1601 of file math.c.

1602{
1603 union { double f; UINT64 i; } u = { num };
1604 return (u.i & ~0ull >> 1) < 0x7ffull << 52;
1605}

◆ _finitef()

int CDECL _finitef ( float  num)

Definition at line 239 of file math.c.

240{
241 union { float f; UINT32 i; } u = { num };
242 return (u.i & 0x7fffffff) < 0x7f800000;
243}

◆ _fpclass()

int CDECL _fpclass ( double  num)

Definition at line 595 of file math.c.

596{
597 union { double f; UINT64 i; } u = { num };
598 int e = u.i >> 52 & 0x7ff;
599 int s = u.i >> 63;
600
601 switch (e)
602 {
603 case 0:
604 if (u.i << 1) return s ? _FPCLASS_ND : _FPCLASS_PD;
605 return s ? _FPCLASS_NZ : _FPCLASS_PZ;
606 case 0x7ff:
607 if (u.i << 12) return ((u.i >> 51) & 1) ? _FPCLASS_QNAN : _FPCLASS_SNAN;
608 return s ? _FPCLASS_NINF : _FPCLASS_PINF;
609 default:
610 return s ? _FPCLASS_NN : _FPCLASS_PN;
611 }
612}
#define _FPCLASS_PZ
Definition: float.h:113
#define _FPCLASS_PD
Definition: float.h:114
#define _FPCLASS_PN
Definition: float.h:115
#define _FPCLASS_ND
Definition: float.h:111
#define _FPCLASS_QNAN
Definition: float.h:108
#define _FPCLASS_NINF
Definition: float.h:109
#define _FPCLASS_NN
Definition: float.h:110
#define _FPCLASS_SNAN
Definition: float.h:107
#define _FPCLASS_NZ
Definition: float.h:112
#define _FPCLASS_PINF
Definition: float.h:116
GLdouble s
Definition: gl.h:2039

◆ _fpclassf()

int CDECL _fpclassf ( float  num)

Definition at line 217 of file math.c.

218{
219 union { float f; UINT32 i; } u = { num };
220 int e = u.i >> 23 & 0xff;
221 int s = u.i >> 31;
222
223 switch (e)
224 {
225 case 0:
226 if (u.i << 1) return s ? _FPCLASS_ND : _FPCLASS_PD;
227 return s ? _FPCLASS_NZ : _FPCLASS_PZ;
228 case 0xff:
229 if (u.i << 9) return ((u.i >> 22) & 1) ? _FPCLASS_QNAN : _FPCLASS_SNAN;
230 return s ? _FPCLASS_NINF : _FPCLASS_PINF;
231 default:
232 return s ? _FPCLASS_NN : _FPCLASS_PN;
233 }
234}

◆ _fpreset()

void CDECL _fpreset ( void  )

Definition at line 1610 of file math.c.

1611{
1612#if (defined(__GNUC__) || defined(__clang__)) && defined(__i386__)
1613 const unsigned int x86_cw = 0x27f;
1614 __asm__ __volatile__( "fninit; fldcw %0" : : "m" (x86_cw) );
1615 if (sse2_supported)
1616 {
1617 unsigned int cw = _MCW_EM, sw = 0;
1618 _setfp_sse(&cw, ~0, &sw, ~0);
1619 }
1620#else
1621 unsigned int cw = _MCW_EM, sw = 0;
1622 _setfp(&cw, ~0, &sw, ~0);
1623#endif
1624}
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tpush %rbx\n" "\t.seh_pushreg %rbx\n" "\tpush %rdi\n" "\t.seh_pushreg %rdi\n" "\tpush %rsi\n" "\t.seh_pushreg %rsi\n" "\tpush %r12\n" "\t.seh_pushreg %r12\n" "\tpush %r13\n" "\t.seh_pushreg %r13\n" "\tpush %r14\n" "\t.seh_pushreg %r14\n" "\tpush %r15\n" "\t.seh_pushreg %r15\n" "\tsub $40, %rsp\n" "\t.seh_stackalloc 40\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $40, %rsp\n" "\tpop %r15\n" "\tpop %r14\n" "\tpop %r13\n" "\tpop %r12\n" "\tpop %rsi\n" "\tpop %rdi\n" "\tpop %rbx\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
SYMCRYPT_ECURVE_INFO_PRECOMP sw

◆ _gcvt()

char *CDECL _gcvt ( double  number,
int  ndigit,
char *  buff 
)

Definition at line 2027 of file math.c.

2028{
2029 if(!buff) {
2030 *_errno() = EINVAL;
2031 return NULL;
2032 }
2033
2034 if(ndigit < 0) {
2035 *_errno() = ERANGE;
2036 return NULL;
2037 }
2038
2039 sprintf(buff, "%.*g", ndigit, number);
2040 return buff;
2041}
#define sprintf
Definition: sprintf.c:45
static const char *static const char const char DWORD void DWORD *static const char const char DWORD void DWORD *static const char DWORD DWORD void * buff
Definition: shcore.c:41

◆ _gcvt_s()

int CDECL _gcvt_s ( char *  buff,
size_t  size,
double  number,
int  digits 
)

Definition at line 2046 of file math.c.

2047{
2048 int len;
2049
2050 if(!buff) {
2051 *_errno() = EINVAL;
2052 return EINVAL;
2053 }
2054
2055 if( digits<0 || digits>=size) {
2056 if(size)
2057 buff[0] = '\0';
2058
2059 *_errno() = ERANGE;
2060 return ERANGE;
2061 }
2062
2063 len = _scprintf("%.*g", digits, number);
2064 if(len > size) {
2065 buff[0] = '\0';
2066 *_errno() = ERANGE;
2067 return ERANGE;
2068 }
2069
2070 sprintf(buff, "%.*g", digits, number);
2071 return 0;
2072}
_ACRTIMP int __cdecl _scprintf(const char *,...) __WINE_CRT_PRINTF_ATTR(1
static const int digits[]
Definition: decode.c:71

◆ _isnan()

int CDECL _isnan ( double  num)

Definition at line 1679 of file math.c.

1680{
1681 union { double f; UINT64 i; } u = { num };
1682 return (u.i & ~0ull >> 1) > 0x7ffull << 52;
1683}

Referenced by fmax(), fmin(), format_float(), fpu_invalid_operation(), ldexp(), nexttowardf(), rpn_acos(), rpn_acosh(), rpn_asin(), rpn_asinh(), rpn_atan(), rpn_atanh(), rpn_cosh(), rpn_pow_f(), rpn_sinh(), rpn_sqr_f(), rpn_tanh(), Test__isnan(), test_isnan(), ulp_error_dbl(), and ulp_error_flt().

◆ _isnanf()

int CDECL _isnanf ( float  num)

Definition at line 248 of file math.c.

249{
250 union { float f; UINT32 i; } u = { num };
251 return (u.i & 0x7fffffff) > 0x7f800000;
252}

Referenced by Test__isnanf().

◆ _matherr()

int CDECL _matherr ( struct _exception *  e)

Definition at line 119 of file math.c.

120{
121 return 0;
122}

◆ _scalb()

double CDECL _scalb ( double  num,
__msvcrt_long  power 
)

Definition at line 2893 of file math.c.

2894{
2895 return ldexp(num, power);
2896}
double CDECL ldexp(double num, int exp)
Definition: math.c:1223
float power
Definition: d3drm.c:3533

◆ _scalbf()

float CDECL _scalbf ( float  num,
__msvcrt_long  power 
)

Definition at line 2903 of file math.c.

2904{
2905 return ldexp(num, power);
2906}

◆ _set_controlfp()

void CDECL _set_controlfp ( unsigned int  newval,
unsigned int  mask 
)

Definition at line 1315 of file math.c.

1316{
1317 _controlfp( newval, mask );
1318}

◆ _set_SSE2_enable()

int CDECL _set_SSE2_enable ( int  flag)

Definition at line 168 of file math.c.

169{
171 return sse2_enabled;
172}
static BOOL sse2_enabled
Definition: math.c:72
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52

◆ _setfp()

static void _setfp ( unsigned int *  cw,
unsigned int  cw_mask,
unsigned int *  sw,
unsigned int  sw_mask 
)
static

Definition at line 842 of file math.c.

844{
845#if (defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)) && defined(__i386__)
846 unsigned long oldcw = 0, newcw = 0;
847 unsigned long oldsw = 0, newsw = 0;
848 unsigned int flags;
849
850 cw_mask &= _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC;
851 sw_mask &= _MCW_EM;
852
853 if (sw)
854 {
855#ifdef _MSC_VER
856 __asm { fstsw newsw }
857#else
858 __asm__ __volatile__( "fstsw %0" : "=m" (newsw) );
859#endif
860 oldsw = newsw;
861
862 flags = 0;
863 if (newsw & 0x1) flags |= _SW_INVALID;
864 if (newsw & 0x2) flags |= _SW_DENORMAL;
865 if (newsw & 0x4) flags |= _SW_ZERODIVIDE;
866 if (newsw & 0x8) flags |= _SW_OVERFLOW;
867 if (newsw & 0x10) flags |= _SW_UNDERFLOW;
868 if (newsw & 0x20) flags |= _SW_INEXACT;
869
870 *sw = (flags & ~sw_mask) | (*sw & sw_mask);
871 TRACE("x86 update sw %08x to %08x\n", flags, *sw);
872 newsw &= ~0x3f;
873 if (*sw & _SW_INVALID) newsw |= 0x1;
874 if (*sw & _SW_DENORMAL) newsw |= 0x2;
875 if (*sw & _SW_ZERODIVIDE) newsw |= 0x4;
876 if (*sw & _SW_OVERFLOW) newsw |= 0x8;
877 if (*sw & _SW_UNDERFLOW) newsw |= 0x10;
878 if (*sw & _SW_INEXACT) newsw |= 0x20;
879 *sw = flags;
880 }
881
882 if (cw)
883 {
884#ifdef _MSC_VER
885 __asm { fstcw newcw }
886#else
887 __asm__ __volatile__( "fstcw %0" : "=m" (newcw) );
888#endif
889 oldcw = newcw;
890
891 flags = 0;
892 if (newcw & 0x1) flags |= _EM_INVALID;
893 if (newcw & 0x2) flags |= _EM_DENORMAL;
894 if (newcw & 0x4) flags |= _EM_ZERODIVIDE;
895 if (newcw & 0x8) flags |= _EM_OVERFLOW;
896 if (newcw & 0x10) flags |= _EM_UNDERFLOW;
897 if (newcw & 0x20) flags |= _EM_INEXACT;
898 switch (newcw & 0xc00)
899 {
900 case 0xc00: flags |= _RC_UP|_RC_DOWN; break;
901 case 0x800: flags |= _RC_UP; break;
902 case 0x400: flags |= _RC_DOWN; break;
903 }
904 switch (newcw & 0x300)
905 {
906 case 0x0: flags |= _PC_24; break;
907 case 0x200: flags |= _PC_53; break;
908 case 0x300: flags |= _PC_64; break;
909 }
910 if (newcw & 0x1000) flags |= _IC_AFFINE;
911
912 *cw = (flags & ~cw_mask) | (*cw & cw_mask);
913 TRACE("x86 update cw %08x to %08x\n", flags, *cw);
914 newcw &= ~0x1f3f;
915 if (*cw & _EM_INVALID) newcw |= 0x1;
916 if (*cw & _EM_DENORMAL) newcw |= 0x2;
917 if (*cw & _EM_ZERODIVIDE) newcw |= 0x4;
918 if (*cw & _EM_OVERFLOW) newcw |= 0x8;
919 if (*cw & _EM_UNDERFLOW) newcw |= 0x10;
920 if (*cw & _EM_INEXACT) newcw |= 0x20;
921 switch (*cw & _MCW_RC)
922 {
923 case _RC_UP|_RC_DOWN: newcw |= 0xc00; break;
924 case _RC_UP: newcw |= 0x800; break;
925 case _RC_DOWN: newcw |= 0x400; break;
926 }
927 switch (*cw & _MCW_PC)
928 {
929 case _PC_64: newcw |= 0x300; break;
930 case _PC_53: newcw |= 0x200; break;
931 case _PC_24: newcw |= 0x0; break;
932 }
933 if (*cw & _IC_AFFINE) newcw |= 0x1000;
934 }
935
936 if (oldsw != newsw && (newsw & 0x3f))
937 {
938 struct {
939 WORD control_word;
940 WORD unused1;
941 WORD status_word;
942 WORD unused2;
943 WORD tag_word;
944 WORD unused3;
945 DWORD instruction_pointer;
946 WORD code_segment;
947 WORD unused4;
948 DWORD operand_addr;
949 WORD data_segment;
950 WORD unused5;
951 } fenv;
952
953 assert(cw);
954
955#ifdef _MSC_VER
956 __asm { fnstenv fenv }
957#else
958 __asm__ __volatile__( "fnstenv %0" : "=m" (fenv) );
959#endif
960 fenv.control_word = newcw;
961 fenv.status_word = newsw;
962#ifdef _MSC_VER
963 __asm { fldenv fenv }
964#else
965 __asm__ __volatile__( "fldenv %0" : : "m" (fenv) : "st", "st(1)",
966 "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)" );
967#endif
968 return;
969 }
970
971 if (oldsw != newsw)
972#ifdef _MSC_VER
973 __asm { fnclex }
974#else
975 __asm__ __volatile__( "fnclex" );
976#endif
977 if (oldcw != newcw)
978#ifdef _MSC_VER
979 __asm { fldcw newcw }
980#else
981 __asm__ __volatile__( "fldcw %0" : : "m" (newcw) );
982#endif
983#elif defined(__x86_64__)
984 _setfp_sse(cw, cw_mask, sw, sw_mask);
985#elif defined(__aarch64__)
986 ULONG_PTR old_fpsr = 0, fpsr = 0, old_fpcr = 0, fpcr = 0;
987 unsigned int flags;
988
989 cw_mask &= _MCW_EM | _MCW_RC;
990 sw_mask &= _MCW_EM;
991
992 if (sw)
993 {
994#ifdef _MSC_VER
995 fpsr = _ReadStatusReg(ARM64_FPSR);
996#else
997 __asm__ __volatile__( "mrs %0, fpsr" : "=r" (fpsr) );
998#endif
999 old_fpsr = fpsr;
1000
1001 flags = 0;
1002 if (fpsr & 0x1) flags |= _SW_INVALID;
1003 if (fpsr & 0x2) flags |= _SW_ZERODIVIDE;
1004 if (fpsr & 0x4) flags |= _SW_OVERFLOW;
1005 if (fpsr & 0x8) flags |= _SW_UNDERFLOW;
1006 if (fpsr & 0x10) flags |= _SW_INEXACT;
1007 if (fpsr & 0x80) flags |= _SW_DENORMAL;
1008
1009 *sw = (flags & ~sw_mask) | (*sw & sw_mask);
1010 TRACE("aarch64 update sw %08x to %08x\n", flags, *sw);
1011 fpsr &= ~0x9f;
1012 if (*sw & _SW_INVALID) fpsr |= 0x1;
1013 if (*sw & _SW_ZERODIVIDE) fpsr |= 0x2;
1014 if (*sw & _SW_OVERFLOW) fpsr |= 0x4;
1015 if (*sw & _SW_UNDERFLOW) fpsr |= 0x8;
1016 if (*sw & _SW_INEXACT) fpsr |= 0x10;
1017 if (*sw & _SW_DENORMAL) fpsr |= 0x80;
1018 *sw = flags;
1019 }
1020
1021 if (cw)
1022 {
1023#ifdef _MSC_VER
1024 fpcr = _ReadStatusReg(ARM64_FPCR);
1025#else
1026 __asm__ __volatile__( "mrs %0, fpcr" : "=r" (fpcr) );
1027#endif
1028 old_fpcr = fpcr;
1029
1030 flags = 0;
1031 if (!(fpcr & 0x100)) flags |= _EM_INVALID;
1032 if (!(fpcr & 0x200)) flags |= _EM_ZERODIVIDE;
1033 if (!(fpcr & 0x400)) flags |= _EM_OVERFLOW;
1034 if (!(fpcr & 0x800)) flags |= _EM_UNDERFLOW;
1035 if (!(fpcr & 0x1000)) flags |= _EM_INEXACT;
1036 if (!(fpcr & 0x8000)) flags |= _EM_DENORMAL;
1037 switch (fpcr & 0xc00000)
1038 {
1039 case 0x400000: flags |= _RC_UP; break;
1040 case 0x800000: flags |= _RC_DOWN; break;
1041 case 0xc00000: flags |= _RC_CHOP; break;
1042 }
1043
1044 *cw = (flags & ~cw_mask) | (*cw & cw_mask);
1045 TRACE("aarch64 update cw %08x to %08x\n", flags, *cw);
1046 fpcr &= ~0xc09f00ul;
1047 if (!(*cw & _EM_INVALID)) fpcr |= 0x100;
1048 if (!(*cw & _EM_ZERODIVIDE)) fpcr |= 0x200;
1049 if (!(*cw & _EM_OVERFLOW)) fpcr |= 0x400;
1050 if (!(*cw & _EM_UNDERFLOW)) fpcr |= 0x800;
1051 if (!(*cw & _EM_INEXACT)) fpcr |= 0x1000;
1052 if (!(*cw & _EM_DENORMAL)) fpcr |= 0x8000;
1053 switch (*cw & _MCW_RC)
1054 {
1055 case _RC_CHOP: fpcr |= 0xc00000; break;
1056 case _RC_UP: fpcr |= 0x400000; break;
1057 case _RC_DOWN: fpcr |= 0x800000; break;
1058 }
1059 }
1060
1061 /* mask exceptions if needed */
1062 if (old_fpcr != fpcr && ~(old_fpcr >> 8) & fpsr & 0x9f != fpsr & 0x9f)
1063 {
1064 ULONG_PTR mask = fpcr & ~0x9f00;
1065#ifdef _MSC_VER
1066 _WriteStatusReg(ARM64_FPCR, mask);
1067#else
1068 __asm__ __volatile__( "msr fpcr, %0" :: "r" (mask) );
1069#endif
1070 }
1071
1072#ifdef _MSC_VER
1073 if (old_fpsr != fpsr)
1074 _WriteStatusReg(ARM64_FPSR, fpsr);
1075 if (old_fpcr != fpcr)
1076 _WriteStatusReg(ARM64_FPCR, fpcr);
1077#else
1078 if (old_fpsr != fpsr)
1079 __asm__ __volatile__( "msr fpsr, %0" :: "r" (fpsr) );
1080 if (old_fpcr != fpcr)
1081 __asm__ __volatile__( "msr fpcr, %0" :: "r" (fpcr) );
1082#endif
1083#elif defined(__arm__)
1084 DWORD old_fpscr, fpscr;
1085 unsigned int flags;
1086
1087 __asm__ __volatile__( "vmrs %0, fpscr" : "=r" (fpscr) );
1088 old_fpscr = fpscr;
1089
1090 cw_mask &= _MCW_EM | _MCW_RC;
1091 sw_mask &= _MCW_EM;
1092
1093 if (sw)
1094 {
1095 flags = 0;
1096 if (fpscr & 0x1) flags |= _SW_INVALID;
1097 if (fpscr & 0x2) flags |= _SW_ZERODIVIDE;
1098 if (fpscr & 0x4) flags |= _SW_OVERFLOW;
1099 if (fpscr & 0x8) flags |= _SW_UNDERFLOW;
1100 if (fpscr & 0x10) flags |= _SW_INEXACT;
1101 if (fpscr & 0x80) flags |= _SW_DENORMAL;
1102
1103 *sw = (flags & ~sw_mask) | (*sw & sw_mask);
1104 TRACE("arm update sw %08x to %08x\n", flags, *sw);
1105 fpscr &= ~0x9f;
1106 if (*sw & _SW_INVALID) fpscr |= 0x1;
1107 if (*sw & _SW_ZERODIVIDE) fpscr |= 0x2;
1108 if (*sw & _SW_OVERFLOW) fpscr |= 0x4;
1109 if (*sw & _SW_UNDERFLOW) fpscr |= 0x8;
1110 if (*sw & _SW_INEXACT) fpscr |= 0x10;
1111 if (*sw & _SW_DENORMAL) fpscr |= 0x80;
1112 *sw = flags;
1113 }
1114
1115 if (cw)
1116 {
1117 flags = 0;
1118 if (!(fpscr & 0x100)) flags |= _EM_INVALID;
1119 if (!(fpscr & 0x200)) flags |= _EM_ZERODIVIDE;
1120 if (!(fpscr & 0x400)) flags |= _EM_OVERFLOW;
1121 if (!(fpscr & 0x800)) flags |= _EM_UNDERFLOW;
1122 if (!(fpscr & 0x1000)) flags |= _EM_INEXACT;
1123 if (!(fpscr & 0x8000)) flags |= _EM_DENORMAL;
1124 switch (fpscr & 0xc00000)
1125 {
1126 case 0x400000: flags |= _RC_UP; break;
1127 case 0x800000: flags |= _RC_DOWN; break;
1128 case 0xc00000: flags |= _RC_CHOP; break;
1129 }
1130
1131 *cw = (flags & ~cw_mask) | (*cw & cw_mask);
1132 TRACE("arm update cw %08x to %08x\n", flags, *cw);
1133 fpscr &= ~0xc09f00ul;
1134 if (!(*cw & _EM_INVALID)) fpscr |= 0x100;
1135 if (!(*cw & _EM_ZERODIVIDE)) fpscr |= 0x200;
1136 if (!(*cw & _EM_OVERFLOW)) fpscr |= 0x400;
1137 if (!(*cw & _EM_UNDERFLOW)) fpscr |= 0x800;
1138 if (!(*cw & _EM_INEXACT)) fpscr |= 0x1000;
1139 if (!(*cw & _EM_DENORMAL)) fpscr |= 0x8000;
1140 switch (*cw & _MCW_RC)
1141 {
1142 case _RC_CHOP: fpscr |= 0xc00000; break;
1143 case _RC_UP: fpscr |= 0x400000; break;
1144 case _RC_DOWN: fpscr |= 0x800000; break;
1145 }
1146 }
1147
1148 if (old_fpscr != fpscr)
1149 __asm__ __volatile__( "vmsr fpscr, %0" :: "r" (fpscr) );
1150#else
1151 FIXME("not implemented\n");
1152 if (cw) *cw = 0;
1153 if (sw) *sw = 0;
1154#endif
1155}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define assert(_expr)
Definition: assert.h:32
#define _IC_AFFINE
Definition: float.h:77
#define _RC_UP
Definition: float.h:80
#define _SW_INEXACT
Definition: float.h:93
#define _PC_64
Definition: float.h:85
#define _SW_OVERFLOW
Definition: float.h:95
#define _EM_UNDERFLOW
Definition: float.h:75
#define _SW_DENORMAL
Definition: float.h:104
#define _EM_ZERODIVIDE
Definition: float.h:73
#define _EM_INEXACT
Definition: float.h:76
#define _EM_OVERFLOW
Definition: float.h:74
#define _EM_INVALID
Definition: float.h:71
#define _PC_24
Definition: float.h:83
#define _SW_ZERODIVIDE
Definition: float.h:96
#define _SW_UNDERFLOW
Definition: float.h:94
#define _RC_DOWN
Definition: float.h:81
#define _RC_CHOP
Definition: float.h:79
#define _SW_INVALID
Definition: float.h:97
#define _PC_53
Definition: float.h:84
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by _clearfp(), _control87(), _fpreset(), and _statusfp().

◆ _statusfp()

unsigned int CDECL _statusfp ( void  )

Definition at line 1175 of file math.c.

1176{
1177 unsigned int flags = 0;
1178#if defined(__i386__)
1179 unsigned int x86_sw, sse2_sw;
1180
1181 _statusfp2( &x86_sw, &sse2_sw );
1182 /* FIXME: there's no definition for ambiguous status, just return all status bits for now */
1183 flags = x86_sw | sse2_sw;
1184#else
1185 _setfp(NULL, 0, &flags, 0);
1186#endif
1187 return flags;
1188}

◆ abs()

int CDECL abs ( int  n)

Definition at line 672 of file math.c.

673{
674 return n >= 0 ? n : -n;
675}

◆ div()

div_t CDECL div ( int  num,
int  denom 
)

Definition at line 2100 of file math.c.

2101{
2102 div_t ret;
2103
2104 ret.quot = num / denom;
2105 ret.rem = num % denom;
2106 return ret;
2107}
return ret
Definition: mutex.c:147
Definition: stdlib.h:47

◆ labs()

Definition at line 680 of file math.c.

681{
682 return n >= 0 ? n : -n;
683}

◆ ldexp()

double CDECL ldexp ( double  num,
int  exp 
)

Definition at line 1223 of file math.c.

1224{
1225 double z = scalbn(num, exp);
1226
1227 if (isfinite(num) && !isfinite(z))
1228 return math_error(_OVERFLOW, "ldexp", num, exp, z);
1229 if (num && isfinite(num) && !z)
1230 return math_error(_UNDERFLOW, "ldexp", num, exp, z);
1231 return z;
1232}
#define isfinite(x)
Definition: math.h:363
_ACRTIMP double __cdecl scalbn(double, int)
Definition: scalbn.c:14
#define _UNDERFLOW
Definition: math.c:65
double math_error(int type, const char *name, double arg1, double arg2, double retval)
Definition: math.c:125
#define _OVERFLOW
Definition: math.c:64
GLdouble GLdouble z
Definition: glext.h:5874
DWORD exp
Definition: msg.c:18625

Referenced by _scalb(), and _scalbf().

◆ ldiv()

ldiv_t CDECL ldiv ( __msvcrt_long  num,
__msvcrt_long  denom 
)

Definition at line 2134 of file math.c.

2135{
2136 ldiv_t ret;
2137
2138 ret.quot = num / denom;
2139 ret.rem = num % denom;
2140 return ret;
2141}
Definition: stdlib.h:52

◆ math_error()

double math_error ( int  type,
const char *  name,
double  arg1,
double  arg2,
double  retval 
)

Definition at line 125 of file math.c.

126{
127 struct _exception exception = {type, (char *)name, arg1, arg2, retval};
128
129 TRACE("(%d, %s, %g, %g, %g)\n", type, debugstr_a(name), arg1, arg2, retval);
130
132 return exception.retval;
133
134 switch (type)
135 {
136 case 0:
137 /* don't set errno */
138 break;
139 case _DOMAIN:
140 *_errno() = EDOM;
141 break;
142 case _SING:
143 case _OVERFLOW:
144 *_errno() = ERANGE;
145 break;
146 case _UNDERFLOW:
147 /* don't set errno */
148 break;
149 default:
150 ERR("Unhandled math error!\n");
151 }
152
153 return exception.retval;
154}
#define ERR(fmt,...)
Definition: precomp.h:57
#define EDOM
Definition: errno.h:54
#define _DOMAIN
Definition: math.c:62
#define _SING
Definition: math.c:63
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
#define debugstr_a
Definition: kernel32.h:31
Definition: name.c:39
int retval
Definition: wcstombs.cpp:91

Referenced by ldexp(), MSVCRT_asin(), MSVCRT_atan(), MSVCRT_atanf(), MSVCRT_exp(), MSVCRT_tanh(), MSVCRT_tanhf(), sqrt_validate(), and sqrtf_validate().

◆ MSVCRT__lrotl()

__msvcrt_ulong CDECL MSVCRT__lrotl ( __msvcrt_ulong  num,
int  shift 
)

Definition at line 627 of file math.c.

628{
629 shift &= 0x1f;
630 return (num << shift) | (num >> (32-shift));
631}
#define shift
Definition: input.c:3280

◆ MSVCRT__lrotr()

__msvcrt_ulong CDECL MSVCRT__lrotr ( __msvcrt_ulong  num,
int  shift 
)

Definition at line 636 of file math.c.

637{
638 shift &= 0x1f;
639 return (num >> shift) | (num << (32-shift));
640}

◆ MSVCRT__rotl()

unsigned int CDECL MSVCRT__rotl ( unsigned int  num,
int  shift 
)

Definition at line 618 of file math.c.

619{
620 shift &= 31;
621 return (num << shift) | (num >> (32-shift));
622}

◆ MSVCRT__rotl64()

unsigned __int64 CDECL MSVCRT__rotl64 ( unsigned __int64  num,
int  shift 
)

Definition at line 654 of file math.c.

655{
656 shift &= 63;
657 return (num << shift) | (num >> (64-shift));
658}

◆ MSVCRT__rotr()

unsigned int CDECL MSVCRT__rotr ( unsigned int  num,
int  shift 
)

Definition at line 645 of file math.c.

646{
647 shift &= 0x1f;
648 return (num >> shift) | (num << (32-shift));
649}

◆ MSVCRT__rotr64()

unsigned __int64 CDECL MSVCRT__rotr64 ( unsigned __int64  num,
int  shift 
)

Definition at line 663 of file math.c.

664{
665 shift &= 63;
666 return (num >> shift) | (num << (64-shift));
667}

◆ MSVCRT_asin()

double CDECL MSVCRT_asin ( double  x)

Definition at line 352 of file math.c.

353{
354#ifdef __i386__
355 unsigned int x87_cw, sse2_cw;
356 unsigned int hx = *(ULONGLONG*)&x >> 32;
357 unsigned int ix = hx & 0x7fffffff;
358
359 if (isnan(x)) return math_error(_DOMAIN, "asin", x, 0, x);
360
361 /* |x| < 1 */
362 if (ix < 0x3ff00000)
363 {
364 __control87_2(0, 0, &x87_cw, &sse2_cw);
365 if (!sse2_enabled || (x87_cw & _MCW_EM) != _MCW_EM
366 || (sse2_cw & (_MCW_EM | _MCW_RC)) != _MCW_EM)
367 return x87_asin(x);
368 }
369#else
370 if (isnan(x)) return x;
371#endif
372
373 return asin( x );
374}
#define isnan(x)
Definition: math.h:360
_ACRTIMP double __cdecl asin(double)
Definition: asin.c:31
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
uint64_t ULONGLONG
Definition: typedefs.h:67

◆ MSVCRT_atan()

double CDECL MSVCRT_atan ( double  x)

Definition at line 380 of file math.c.

381{
382 if (isnan(x)) return math_error(_DOMAIN, "atan", x, 0, x);
383 return atan( x );
384}
_ACRTIMP double __cdecl atan(double)
Definition: atan.c:77

◆ MSVCRT_atanf()

float CDECL MSVCRT_atanf ( float  x)

Definition at line 258 of file math.c.

259{
260 if (isnan(x)) return math_error(_DOMAIN, "atanf", x, 0, x);
261 return atanf( x );
262}
_ACRTIMP float __cdecl atanf(float)
Definition: atanf.c:47

◆ MSVCRT_exp()

double CDECL MSVCRT_exp ( double  x)

Definition at line 391 of file math.c.

392{
393 if (isnan( x )) return math_error(_DOMAIN, "exp", x, 0, 1.0 + x);
394 return exp( x );
395}

◆ msvcrt_init_math()

void msvcrt_init_math ( void *  module)

Definition at line 74 of file math.c.

75{
77#if _MSVCR_VER <=71
79#else
81#endif
82}
#define FALSE
Definition: types.h:117
BOOL WINAPI IsProcessorFeaturePresent(IN DWORD ProcessorFeature)
Definition: sysinfo.c:169
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE
Definition: ketypes.h:186

◆ MSVCRT_sqrt()

double CDECL MSVCRT_sqrt ( double  x)

Definition at line 452 of file math.c.

453{
454 if (!sqrt_validate(&x, TRUE))
455 return x;
456
457 return asm_sqrt(x);
458}
#define TRUE
Definition: types.h:120
static BOOL sqrt_validate(double *x, BOOL update_sw)
Definition: math.c:400

◆ MSVCRT_sqrtf()

float CDECL MSVCRT_sqrtf ( float  x)

Definition at line 303 of file math.c.

304{
305#ifndef __i386__
306 if (!sqrtf_validate(&x))
307 return x;
308
309 return asm_sqrtf(x);
310#else
311 return sqrtf( x );
312#endif
313}
static BOOL sqrtf_validate(float *x)
Definition: math.c:268
#define sqrtf(x)
Definition: mymath.h:59

◆ MSVCRT_tanh()

double CDECL MSVCRT_tanh ( double  x)

Definition at line 464 of file math.c.

465{
466 if (isnan( x ))
467 {
468 *(UINT64*)&x |= 0x0008000000000000ULL;
469 return math_error(_DOMAIN, "tanh", x, 0, x);
470 }
471 return tanh( x );
472}
_ACRTIMP double __cdecl tanh(double)
Definition: tanh.c:46

◆ MSVCRT_tanhf()

float CDECL MSVCRT_tanhf ( float  x)

Definition at line 319 of file math.c.

320{
321 if (isnan( x ))
322 {
323 *(UINT32*)&x |= 0x400000;
324 return math_error(_DOMAIN, "tanhf", x, 0, x);
325 }
326 return tanhf( x );
327}
_ACRTIMP float __cdecl tanhf(float)
Definition: tanhf.c:49

◆ ret_nan()

static double ret_nan ( BOOL  update_sw)
inlinestatic

Definition at line 84 of file math.c.

85{
86 double x = 1.0;
87 if (!update_sw) return -NAN;
88 return (x - x) / (x - x);
89}
#define NAN
Definition: math.h:273

Referenced by JSGlobal_parseFloat(), sqrt_validate(), and sqrtf_validate().

◆ sqrt_validate()

static BOOL sqrt_validate ( double *  x,
BOOL  update_sw 
)
static

Definition at line 400 of file math.c.

401{
402 short c = _dclass(*x);
403
404 if (c == FP_ZERO) return FALSE;
405 if (c == FP_NAN)
406 {
407#ifdef __i386__
408 if (update_sw)
409 *x = math_error(_DOMAIN, "sqrt", *x, 0, *x);
410#else
411 /* set signaling bit */
412 *(ULONGLONG*)x |= 0x8000000000000ULL;
413#endif
414 return FALSE;
415 }
416 if (signbit(*x))
417 {
418 *x = math_error(_DOMAIN, "sqrt", *x, 0, ret_nan(update_sw));
419 return FALSE;
420 }
421 if (c == FP_INFINITE) return FALSE;
422 return TRUE;
423}
#define FP_NAN
Definition: math.h:278
#define FP_ZERO
Definition: math.h:281
#define FP_INFINITE
Definition: math.h:277
#define signbit(x)
Definition: math.h:362
static double ret_nan(BOOL update_sw)
Definition: math.c:84
short CDECL _dclass(double x)
const GLubyte * c
Definition: glext.h:8905

Referenced by MSVCRT_sqrt().

◆ sqrtf_validate()

static BOOL sqrtf_validate ( float *  x)
static

Definition at line 268 of file math.c.

269{
270 short c = _fdclass(*x);
271
272 if (c == FP_ZERO) return FALSE;
273 if (c == FP_NAN) return FALSE;
274 if (signbit(*x))
275 {
276 *x = math_error(_DOMAIN, "sqrtf", *x, 0, ret_nan(TRUE));
277 return FALSE;
278 }
279 if (c == FP_INFINITE) return FALSE;
280 return TRUE;
281}
short CDECL _fdclass(float x)

Referenced by MSVCRT_sqrtf().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msvcrt  )

Variable Documentation

◆ MSVCRT_default_matherr_func

MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL
static

Definition at line 69 of file math.c.

Referenced by __setusermatherr(), and math_error().

◆ sse2_enabled

BOOL sse2_enabled
static

Definition at line 72 of file math.c.

Referenced by _set_SSE2_enable(), MSVCRT_asin(), and msvcrt_init_math().

◆ sse2_supported

BOOL sse2_supported

Definition at line 71 of file math.c.

Referenced by _clearfp(), _control87(), _fpreset(), _set_SSE2_enable(), memmove(), and msvcrt_init_math().