Added some float and stdlib functions

svn path=/trunk/; revision=2027
This commit is contained in:
Eric Kohl 2001-07-02 21:52:25 +00:00
parent 8dacbd3ab0
commit 49ad46d964
26 changed files with 898 additions and 99 deletions

View file

@ -0,0 +1,199 @@
/*
* float.h
*
* Constants related to floating point arithmetic.
*
* Also included here are some non-ANSI bits for accessing the floating
* point controller.
*
* NOTE: GCC provides float.h, and it is probably more accurate than this,
* but it doesn't include the non-standard stuff for accessing the
* fp controller. (TODO: Move those bits elsewhere?) Thus it is
* probably not a good idea to use the GCC supplied version instead
* of this header.
*
* This file is part of the Mingw32 package.
*
* Contributors:
* Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Revision: 1.1 $
* $Author: ekohl $
* $Date: 2001/07/02 21:52:25 $
*
*/
#ifndef _FLOAT_H_
#define _FLOAT_H_
#ifdef __cplusplus
extern "C" {
#endif
#define FLT_ROUNDS 1
#define FLT_GUARD 1
#define FLT_NORMALIZE 1
/*
* The characteristics of float.
*/
/* The radix for floating point representation. */
#define FLT_RADIX 2
/* Decimal digits of precision. */
#define FLT_DIG 6
/* Smallest number such that 1+x != 1 */
#define FLT_EPSILON 1.19209290e-07F
/* The number of base FLT_RADIX digits in the mantissa. */
#define FLT_MANT_DIG 24
/* The maximum floating point number. */
#define FLT_MAX 3.40282347e+38F
/* Maximum n such that FLT_RADIX^n - 1 is representable. */
#define FLT_MAX_EXP 128
/* Maximum n such that 10^n is representable. */
#define FLT_MAX_10_EXP 38
/* Minimum normalized floating-point number. */
#define FLT_MIN 1.17549435e-38F
/* Minimum n such that FLT_RADIX^n is a normalized number. */
#define FLT_MIN_EXP (-125)
/* Minimum n such that 10^n is a normalized number. */
#define FLT_MIN_10_EXP (-37)
/*
* The characteristics of double.
*/
#define DBL_DIG 15
#define DBL_EPSILON 1.1102230246251568e-16
#define DBL_MANT_DIG 53
#define DBL_MAX 1.7976931348623157e+308
#define DBL_MAX_EXP 1024
#define DBL_MAX_10_EXP 308
#define DBL_MIN 2.2250738585072014e-308
#define DBL_MIN_EXP (-1021)
#define DBL_MIN_10_EXP (-307)
/*
* The characteristics of long double.
* NOTE: long double is the same as double.
*/
#define LDBL_DIG 15
#define LDBL_EPSILON 1.1102230246251568e-16L
#define LDBL_MANT_DIG 53
#define LDBL_MAX 1.7976931348623157e+308L
#define LDBL_MAX_EXP 1024
#define LDBL_MAX_10_EXP 308
#define LDBL_MIN 2.2250738585072014e-308L
#define LDBL_MIN_EXP (-1021)
#define LDBL_MIN_10_EXP (-307)
/*
* Functions and definitions for controlling the FPU.
*/
#ifndef __STRICT_ANSI__
/* TODO: These constants are only valid for x86 machines */
/* Control word masks for unMask */
#define _MCW_EM 0x0008001F /* Error masks */
#define _MCW_IC 0x00040000 /* Infinity */
#define _MCW_RC 0x00000300 /* Rounding */
#define _MCW_PC 0x00030000 /* Precision */
/* Control word values for unNew (use with related unMask above) */
#define _EM_INVALID 0x00000010
#define _EM_DENORMAL 0x00080000
#define _EM_ZERODIVIDE 0x00000008
#define _EM_OVERFLOW 0x00000004
#define _EM_UNDERFLOW 0x00000002
#define _EM_INEXACT 0x00000001
#define _IC_AFFINE 0x00040000
#define _IC_PROJECTIVE 0x00000000
#define _RC_CHOP 0x00000300
#define _RC_UP 0x00000200
#define _RC_DOWN 0x00000100
#define _RC_NEAR 0x00000000
#define _PC_24 0x00020000
#define _PC_53 0x00010000
#define _PC_64 0x00000000
/* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask),
* i.e. change the bits in unMask to have the values they have in unNew,
* leaving other bits unchanged. */
unsigned int _controlfp (unsigned int unNew, unsigned int unMask);
unsigned int _control87 (unsigned int unNew, unsigned int unMask);
unsigned int _clearfp (void); /* Clear the FPU status word */
unsigned int _statusfp (void); /* Report the FPU status word */
#define _clear87 _clearfp
#define _status87 _statusfp
void _fpreset (void); /* Reset the FPU */
/* Global 'variable' for the current floating point error code. */
extern int * __fpecode(void);
#define _fpecode (*(__fpecode()))
/*
* IEEE recommended functions
*/
double _chgsign (double x);
double _copysign (double dTo, double dFrom);
double _logb (double x);
double _nextafter (double x, double y);
double _scalb (double x, long n);
/* Return values for fpclass. */
#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */
#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */
#define _FPCLASS_NINF 0x0004 /* Negative Infinity */
#define _FPCLASS_NN 0x0008 /* Negative Normal */
#define _FPCLASS_ND 0x0010 /* Negative Denormal */
#define _FPCLASS_NZ 0x0020 /* Negative Zero */
#define _FPCLASS_PZ 0x0040 /* Positive Zero */
#define _FPCLASS_PD 0x0080 /* Positive Denormal */
#define _FPCLASS_PN 0x0100 /* Positive Normal */
#define _FPCLASS_PINF 0x0200 /* Positive Infinity */
int _finite (double x);
int _fpclass (double x);
int _isnan (double x);
int _isinf (double x); // not exported
int _isnanl (long double x); // not exported
int _isinfl (long double x); // not exported
#define isnan(x) _isnan(x)
#define isinf(x) _isinf(x)
#endif /* Not __STRICT_ANSI__ */
#ifdef __cplusplus
}
#endif
#endif /* _FLOAT_H_ */

View file

@ -0,0 +1,27 @@
#ifndef _IEEE_H
#define _IEEE_H
typedef struct {
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int sign:1;
} float_t;
typedef struct {
unsigned int mantissal:32;
unsigned int mantissah:20;
unsigned int exponent:11;
unsigned int sign:1;
} double_t;
typedef struct {
unsigned int mantissal:32;
unsigned int mantissah:32;
unsigned int exponent:15;
unsigned int sign:1;
unsigned int empty:16;
} long_double_t;
#endif

View file

@ -7,12 +7,16 @@
typedef struct _ThreadData typedef struct _ThreadData
{ {
int terrno; int terrno;
unsigned long tdoserrno; unsigned long tdoserrno;
unsigned long long tnext; /* used by rand/srand */ unsigned long long tnext; /* used by rand/srand */
char *lasttoken; /* used by strtok */
wchar_t *wlasttoken; /* used by wcstok */
int fpecode; /* fp exception code */
char *lasttoken; /* used by strtok */
wchar_t *wlasttoken; /* used by wcstok */
} THREADDATA, *PTHREADDATA; } THREADDATA, *PTHREADDATA;

View file

@ -0,0 +1,161 @@
/*
* math.h
*
* Mathematical functions.
*
* This file is part of the Mingw32 package.
*
* Contributors:
* Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Revision: 1.1 $
* $Author: ekohl $
* $Date: 2001/07/02 21:52:25 $
*
*/
// added modfl
#ifndef _MATH_H_
#define _MATH_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* HUGE_VAL is returned by strtod when the value would overflow the
* representation of 'double'. There are other uses as well.
*
* __imp__HUGE is a pointer to the actual variable _HUGE in
* MSVCRT.DLL. If we used _HUGE directly we would get a pointer
* to a thunk function.
*
* NOTE: The CRTDLL version uses _HUGE_dll instead.
*/
#if __MSVCRT__
extern double* __imp__HUGE;
#define HUGE_VAL (*__imp__HUGE)
#else
/* CRTDLL */
extern double* _HUGE_dll;
#define HUGE_VAL (*_HUGE_dll)
#endif
struct _exception
{
int type;
char *name;
double arg1;
double arg2;
double retval;
};
/*
* Types for the above _exception structure.
*/
#define _DOMAIN 1 /* domain error in argument */
#define _SING 2 /* singularity */
#define _OVERFLOW 3 /* range overflow */
#define _UNDERFLOW 4 /* range underflow */
#define _TLOSS 5 /* total loss of precision */
#define _PLOSS 6 /* partial loss of precision */
/*
* Exception types with non-ANSI names for compatibility.
*/
#ifndef __STRICT_ANSI__
#ifndef _NO_OLDNAMES
#define DOMAIN _DOMAIN
#define SING _SING
#define OVERFLOW _OVERFLOW
#define UNDERFLOW _UNDERFLOW
#define TLOSS _TLOSS
#define PLOSS _PLOSS
#endif /* Not _NO_OLDNAMES */
#endif /* Not __STRICT_ANSI__ */
double sin (double x);
double cos (double x);
double tan (double x);
double sinh (double x);
double cosh (double x);
double tanh (double x);
double asin (double x);
double acos (double x);
double atan (double x);
double atan2 (double y, double x);
double exp (double x);
double log (double x);
double log10 (double x);
double pow (double x, double y);
long double powl (long double x,long double y);
double sqrt (double x);
double ceil (double x);
double floor (double x);
double fabs (double x);
double ldexp (double x, int n);
double frexp (double x, int* exp);
double modf (double x, double* ip);
long double modfl (long double x,long double* ip);
double fmod (double x, double y);
#ifndef __STRICT_ANSI__
/* Complex number (for cabs) */
struct _complex
{
double x; /* Real part */
double y; /* Imaginary part */
};
double _cabs (struct _complex x);
double _hypot (double x, double y);
double _j0 (double x);
double _j1 (double x);
double _jn (int n, double x);
double _y0 (double x);
double _y1 (double x);
double _yn (int n, double x);
#ifndef _NO_OLDNAMES
/*
* Non-underscored versions of non-ANSI functions. These reside in
* liboldnames.a. Provided for extra portability.
*/
double cabs (struct _complex x);
double hypot (double x, double y);
double j0 (double x);
double j1 (double x);
double jn (int n, double x);
double y0 (double x);
double y1 (double x);
double yn (int n, double x);
#endif /* Not _NO_OLDNAMES */
#endif /* Not __STRICT_ANSI__ */
#ifdef __cplusplus
}
#endif
#endif /* Not _MATH_H_ */

View file

@ -18,9 +18,9 @@
* DISCLAMED. This includes but is not limited to warranties of * DISCLAMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* *
* $Revision: 1.1 $ * $Revision: 1.2 $
* $Author: ekohl $ * $Author: ekohl $
* $Date: 2000/12/03 17:49:21 $ * $Date: 2001/07/02 21:52:25 $
* *
*/ */
/* Appropriated for Reactos Crtdll by Ariadne */ /* Appropriated for Reactos Crtdll by Ariadne */
@ -55,9 +55,12 @@ extern char*** _environ_dll;
#include <msvcrt/mbstring.h> #include <msvcrt/mbstring.h>
#ifndef __ATTRIB_NORETURN #ifndef __ATTRIB_NORETURN
#ifdef __GNUC__ #ifdef __GNUC__
#define _ATTRIB_NORETURN __attribute__ ((noreturn)) #define _ATTRIB_NORETURN __attribute__ ((noreturn))
#ifndef __int64
#define __int64 long long
#endif /* Not __int64 */
#else /* Not __GNUC__ */ #else /* Not __GNUC__ */
#define _ATTRIB_NORETURN #define _ATTRIB_NORETURN
#endif /* __GNUC__ */ #endif /* __GNUC__ */
@ -168,12 +171,16 @@ char* _fullpath( char* caBuf, const char* szPath, size_t sizeMax );
wchar_t *_wfullpath( wchar_t *absPath, const wchar_t *relPath, size_t maxLength ); wchar_t *_wfullpath( wchar_t *absPath, const wchar_t *relPath, size_t maxLength );
char* _itoa (int nValue, char* sz, int nRadix); char* _itoa (int nValue, char* sz, int nRadix);
char* _i64toa(__int64 value, char *string, int radix);
char* _ltoa (long lnValue, char* sz, int nRadix); char* _ltoa (long lnValue, char* sz, int nRadix);
char* _ultoa(unsigned long value, char *string, int radix); char* _ultoa(unsigned long value, char *string, int radix);
char* _ui64toa(unsigned __int64 value, char *string, int radix);
wchar_t* _itow (int nValue, wchar_t* sz, int nRadix); wchar_t* _itow (int nValue, wchar_t* sz, int nRadix);
wchar_t* _i64tow(__int64 value, wchar_t *string, int radix);
wchar_t* _ltow (long lnValue, wchar_t* sz, int nRadix); wchar_t* _ltow (long lnValue, wchar_t* sz, int nRadix);
wchar_t* _ultow(unsigned long value, wchar_t *string, int radix); wchar_t* _ultow(unsigned long value, wchar_t *string, int radix);
wchar_t* _ui64tow(unsigned __int64 value, wchar_t *string, int radix);
char* _ecvt (double dValue, int nDig, int* pnDec, int* pnSign); char* _ecvt (double dValue, int nDig, int* pnDec, int* pnSign);
char* _fcvt (double dValue, int nDig, int* pnDec, int* pnSign); char* _fcvt (double dValue, int nDig, int* pnDec, int* pnSign);
@ -186,7 +193,10 @@ unsigned int _rotr( unsigned int value, int shift );
unsigned long _lrotl( unsigned long value, int shift ); unsigned long _lrotl( unsigned long value, int shift );
unsigned long _lrotr( unsigned long value, int shift ); unsigned long _lrotr( unsigned long value, int shift );
__int64 _atoi64(const char *szNumber);
int _wtoi( const wchar_t *str ); int _wtoi( const wchar_t *str );
__int64 _wtoi64(const wchar_t *str);
long _wtol( const wchar_t *str ); long _wtol( const wchar_t *str );

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.11 2001/04/10 19:20:37 ekohl Exp $ # $Id: Makefile,v 1.12 2001/07/02 21:51:18 ekohl Exp $
# #
# ReactOS Operating System # ReactOS Operating System
# #
@ -50,9 +50,18 @@ OBJECTS_EXCEPT = \
except/xcptfil.o except/xcptfil.o
OBJECTS_FLOAT = \ OBJECTS_FLOAT = \
float/chgsign.o \
float/clearfp.o \
float/cntrlfp.o \ float/cntrlfp.o \
float/copysign.o \
float/fpclass.o \
float/fpecode.o \
float/fpreset.o \ float/fpreset.o \
float/isnan.o float/isnan.o \
float/logb.o \
float/nafter.o \
float/scalb.o \
float/statfp.o
OBJECTS_IO = \ OBJECTS_IO = \
io/access.o \ io/access.o \
@ -131,6 +140,7 @@ OBJECTS_STDLIB = \
stdlib/atexit.o \ stdlib/atexit.o \
stdlib/atof.o \ stdlib/atof.o \
stdlib/atoi.o \ stdlib/atoi.o \
stdlib/atoi64.o \
stdlib/atol.o \ stdlib/atol.o \
stdlib/bsearch.o \ stdlib/bsearch.o \
stdlib/div.o \ stdlib/div.o \
@ -157,7 +167,8 @@ OBJECTS_STDLIB = \
stdlib/wcstod.o \ stdlib/wcstod.o \
stdlib/wcstol.o \ stdlib/wcstol.o \
stdlib/wcstoul.o \ stdlib/wcstoul.o \
stdlib/wtoi.o stdlib/wtoi.o \
stdlib/wtoi64.o
OBJECTS_STRING = \ OBJECTS_STRING = \
string/memccpy.o \ string/memccpy.o \

View file

@ -0,0 +1,13 @@
#include <msvcrt/float.h>
#include <msvcrt/internal/ieee.h>
double _chgsign( double __x )
{
double_t *x = (double_t *)&x;
if ( x->sign == 1 )
x->sign = 0;
else
x->sign = 1;
return __x;
}

View file

@ -0,0 +1,13 @@
#include <msvcrt/float.h>
unsigned int _clearfp (void)
{
unsigned short __res = _statusfp();
__asm__ __volatile__ (
"fclex \n\t"
);
return __res;
}

View file

@ -1,16 +1,16 @@
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <crtdll/float.h> #include <msvcrt/float.h>
unsigned int _controlfp (unsigned int unNew, unsigned int unMask) unsigned int _controlfp(unsigned int unNew, unsigned int unMask)
{ {
return _control87(unNew,unMask); return _control87(unNew,unMask);
} }
unsigned int _control87 (unsigned int unNew, unsigned int unMask) unsigned int _control87(unsigned int unNew, unsigned int unMask)
{ {
register unsigned int __res; register unsigned int __res;
__asm__ __volatile__ ( __asm__ __volatile__ (
"pushl %%eax \n\t" /* make room on stack */ "pushl %%eax \n\t" /* make room on stack */
"fstcw (%%esp) \n\t" "fstcw (%%esp) \n\t"
@ -30,9 +30,7 @@ __asm__ __volatile__ (
"fldcw (%%esp) \n\t" "fldcw (%%esp) \n\t"
"popl %%edx \n\t" "popl %%edx \n\t"
:"=r" (__res):"r" (unNew),"r" (unMask): "ax", "dx", "cx"); :"=r" (__res):"r" (unNew),"r" (unMask): "ax", "dx", "cx");
/* :"=a" (__res):"c" (unNew),"d" (unMask):"ax", "dx", "cx"); */
return __res; return __res;
} }

View file

@ -0,0 +1,12 @@
#include <msvcrt/float.h>
#include <msvcrt/internal/ieee.h>
double _copysign (double __d, double __s)
{
double_t *d = (double_t *)&__d;
double_t *s = (double_t *)&__s;
d->sign = s->sign;
return __d;
}

View file

@ -0,0 +1,65 @@
#include <msvcrt/float.h>
#include <msvcrt/math.h>
#include <msvcrt/internal/ieee.h>
#define _FPCLASS_SNAN 0x0001 /* signaling NaN */
#define _FPCLASS_QNAN 0x0002 /* quiet NaN */
#define _FPCLASS_NINF 0x0004 /* negative infinity */
#define _FPCLASS_NN 0x0008 /* negative normal */
#define _FPCLASS_ND 0x0010 /* negative denormal */
#define _FPCLASS_NZ 0x0020 /* -0 */
#define _FPCLASS_PZ 0x0040 /* +0 */
#define _FPCLASS_PD 0x0080 /* positive denormal */
#define _FPCLASS_PN 0x0100 /* positive normal */
#define _FPCLASS_PINF 0x0200 /* positive infinity */
#define FP_SNAN 0x0001 // signaling NaN
#define FP_QNAN 0x0002 // quiet NaN
#define FP_NINF 0x0004 // negative infinity
#define FP_PINF 0x0200 // positive infinity
#define FP_NDENORM 0x0008 // negative denormalized non-zero
#define FP_PDENORM 0x0010 // positive denormalized non-zero
#define FP_NZERO 0x0020 // negative zero
#define FP_PZERO 0x0040 // positive zero
#define FP_NNORM 0x0080 // negative normalized non-zero
#define FP_PNORM 0x0100 // positive normalized non-zero
typedef int fpclass_t;
fpclass_t _fpclass(double __d)
{
double_t *d = (double_t *)&__d;
if ( d->exponent == 0 ) {
if ( d->mantissah == 0 && d->mantissal == 0 ) {
if ( d->sign ==0 )
return FP_NZERO;
else
return FP_PZERO;
} else {
if ( d->sign ==0 )
return FP_NDENORM;
else
return FP_PDENORM;
}
}
if (d->exponent == 0x7ff ) {
if ( d->mantissah == 0 && d->mantissal == 0 ) {
if ( d->sign ==0 )
return FP_NINF;
else
return FP_PINF;
}
else if ( d->mantissah == 0 && d->mantissal != 0 ) {
return FP_QNAN;
}
else if ( d->mantissah == 0 && d->mantissal != 0 ) {
return FP_SNAN;
}
}
return 0;
}

View file

@ -0,0 +1,7 @@
#include <msvcrt/float.h>
#include <msvcrt/internal/tls.h>
int * __fpecode(void)
{
return(&(GetThreadData()->fpecode));
}

View file

@ -1,8 +1,8 @@
#include <crtdll/float.h> #include <msvcrt/float.h>
void _fpreset (void) void _fpreset(void)
{ {
/* FIXME: This causes an exception */ /* FIXME: This causes an exception */
// __asm__ __volatile__("fninit\n\t"); // __asm__ __volatile__("fninit\n\t");
return; return;
} }

View file

@ -16,9 +16,9 @@ License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave, not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */ Cambridge, MA 02139, USA. */
#include <crtdll/math.h> #include <msvcrt/math.h>
#include <crtdll/float.h> #include <msvcrt/float.h>
#include <crtdll/internal/ieee.h> #include <msvcrt/internal/ieee.h>
int _isnan(double __x) int _isnan(double __x)
{ {

View file

@ -0,0 +1,31 @@
/* Math functions for i387.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by John C. Bowman <bowman@ipp-garching.mpg.de>, 1995.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <msvcrt/float.h>
double _logb (double __x)
{
register double __value, __junk;
__asm __volatile__
("fxtract\n\t"
: "=t" (__junk), "=u" (__value) : "0" (__x));
return __value;
}

View file

@ -0,0 +1,12 @@
#include <msvcrt/float.h>
double _nextafter( double x, double y )
{
if ( x == y)
return x;
if ( isnan(x) || isnan(y) )
return x;
return x;
}

View file

@ -0,0 +1,11 @@
#include <msvcrt/float.h>
#include <msvcrt/internal/ieee.h>
double _scalb( double __x, long e )
{
double_t *x = (double_t *)&__x;
x->exponent += e;
return __x;
}

View file

@ -0,0 +1,14 @@
#include <msvcrt/float.h>
unsigned int _statusfp (void)
{
register unsigned short __res;
__asm__ __volatile__ (
"fstsw %0 \n\t"
// "movzwl %ax, %eax"
:"=a" (__res)
);
return __res;
}

View file

@ -10,9 +10,9 @@
* ==================================================== * ====================================================
*/ */
#include <crtdll/float.h> #include <msvcrt/float.h>
#include <crtdll/math.h> #include <msvcrt/math.h>
#include <crtdll/internal/ieee.h> #include <msvcrt/internal/ieee.h>
@ -20,7 +20,6 @@
double modf(double __x, double *__i) double modf(double __x, double *__i)
{ {
double_t * x = (double_t *)&__x; double_t * x = (double_t *)&__x;
double_t * iptr = ( double_t *)__i; double_t * iptr = ( double_t *)__i;
@ -39,7 +38,7 @@ double modf(double __x, double *__i)
return 0.0; return 0.0;
} }
i = (0x000fffff)>>j0; i = (0x000fffff)>>j0;
iptr->sign = x->sign; iptr->sign = x->sign;
iptr->exponent = x->exponent; iptr->exponent = x->exponent;
iptr->mantissah = x->mantissah&(~i); iptr->mantissah = x->mantissah&(~i);
@ -48,48 +47,43 @@ double modf(double __x, double *__i)
__x = 0.0; __x = 0.0;
x->sign = iptr->sign; x->sign = iptr->sign;
return __x; return __x;
} }
return __x - *__i; return __x - *__i;
} }
} else if (j0>51) { /* no fraction part */ } else if (j0>51) { /* no fraction part */
*__i = __x; *__i = __x;
if ( _isnan(__x) || _isinf(__x) ) if ( _isnan(__x) || _isinf(__x) )
return __x; return __x;
__x = 0.0;
x->sign = iptr->sign;
return __x;
} else { /* fraction part in low x */
i = ((unsigned)(0xffffffff))>>(j0-20);
iptr->sign = x->sign;
iptr->exponent = x->exponent;
iptr->mantissah = x->mantissah;
iptr->mantissal = x->mantissal&(~i);
if ( __x == *__i ) {
__x = 0.0; __x = 0.0;
x->sign = iptr->sign; x->sign = iptr->sign;
return __x; return __x;
} else { /* fraction part in low x */ }
return __x - *__i;
i = ((unsigned)(0xffffffff))>>(j0-20);
iptr->sign = x->sign;
iptr->exponent = x->exponent;
iptr->mantissah = x->mantissah;
iptr->mantissal = x->mantissal&(~i);
if ( __x == *__i ) {
__x = 0.0;
x->sign = iptr->sign;
return __x;
}
return __x - *__i;
} }
} }
long double modfl(long double __x, long double *__i) long double modfl(long double __x, long double *__i)
{ {
long_double_t * x = (long_double_t *)&__x; long_double_t * x = (long_double_t *)&__x;
long_double_t * iptr = (long_double_t *)__i; long_double_t * iptr = (long_double_t *)__i;
int j0; int j0;
unsigned int i; unsigned int i;
j0 = x->exponent - 0x3fff; /* exponent of x */ j0 = x->exponent - 0x3fff; /* exponent of x */
if(j0<32) { /* integer part in high x */ if(j0<32) { /* integer part in high x */
if(j0<0) { /* |x|<1 */ if(j0<0) { /* |x|<1 */
*__i = 0.0L; *__i = 0.0L;
@ -97,7 +91,7 @@ long double modfl(long double __x, long double *__i)
return __x; return __x;
} else { } else {
i = ((unsigned int)(0xffffffff))>>(j0+1); i = ((unsigned int)(0xffffffff))>>(j0+1);
if ( x->mantissal == 0 && (x->mantissal & i) == 0 ) { if ( x->mantissal == 0 && (x->mantissal & i) == 0 ) {
*__i = __x; *__i = __x;
__x = 0.0L; __x = 0.0L;
@ -106,36 +100,33 @@ long double modfl(long double __x, long double *__i)
} }
iptr->sign = x->sign; iptr->sign = x->sign;
iptr->exponent = x->exponent; iptr->exponent = x->exponent;
iptr->mantissah = x->mantissah&((~i)); iptr->mantissah = x->mantissah&((~i));
iptr->mantissal = 0; iptr->mantissal = 0;
return __x - *__i;
return __x - *__i;
} }
} else if (j0>63) { /* no fraction part */ } else if (j0>63) { /* no fraction part */
*__i = __x; *__i = __x;
if ( _isnanl(__x) || _isinfl(__x) ) if ( _isnanl(__x) || _isinfl(__x) )
return __x; return __x;
__x = 0.0L;
x->sign = iptr->sign;
return __x;
} else { /* fraction part in low x */
i = ((unsigned int)(0xffffffff))>>(j0-32);
if ( x->mantissal == 0 ) {
*__i = __x;
__x = 0.0L; __x = 0.0L;
x->sign = iptr->sign; x->sign = iptr->sign;
return __x; return __x;
} else { /* fraction part in low x */ }
iptr->sign = x->sign;
i = ((unsigned int)(0xffffffff))>>(j0-32); iptr->exponent = x->exponent;
if ( x->mantissal == 0 ) { iptr->mantissah = x->mantissah;
*__i = __x; iptr->mantissal = x->mantissal&(~i);
__x = 0.0L;
x->sign = iptr->sign;
return __x;
}
iptr->sign = x->sign;
iptr->exponent = x->exponent;
iptr->mantissah = x->mantissah;
iptr->mantissal = x->mantissal&(~i);
return __x - *__i; return __x - *__i;
} }
} }

View file

@ -78,6 +78,7 @@ double pow (double __x, double __y)
return __value; return __value;
} }
long double powl (long double __x,long double __y) long double powl (long double __x,long double __y)
{ {
return pow(__x,__y/2)*pow(__x,__y/2); return pow(__x,__y/2)*pow(__x,__y/2);

View file

@ -13,6 +13,8 @@ static void InitThreadData(PTHREADDATA ThreadData)
// ThreadData->terrno = 0; // ThreadData->terrno = 0;
// ThreadData->tdoserrno = 0; // ThreadData->tdoserrno = 0;
ThreadData->fpecode = 0;
/* FIXME: init more thread local data */ /* FIXME: init more thread local data */
} }

View file

@ -1,4 +1,4 @@
; $Id: msvcrt.def,v 1.6 2001/04/10 19:20:37 ekohl Exp $ ; $Id: msvcrt.def,v 1.7 2001/07/02 21:51:18 ekohl Exp $
; ;
; ReactOS MSVCRT Compatibility Library ; ReactOS MSVCRT Compatibility Library
; ;
@ -97,7 +97,7 @@ __argv
; __crtLCMapStringA ; __crtLCMapStringA
__dllonexit __dllonexit
; __doserrno ; __doserrno
; __fpecode __fpecode
__getmainargs __getmainargs
; __initenv ; __initenv
__isascii __isascii
@ -172,7 +172,7 @@ _aexit_rtn
_amsg_exit _amsg_exit
_assert _assert
; _atodbl ; _atodbl
; _atoi64 _atoi64
; _atoldbl ; _atoldbl
_beep _beep
_beginthread _beginthread
@ -184,17 +184,17 @@ _cexit
; _cgets ; _cgets
_chdir _chdir
_chdrive _chdrive
; _chgsign _chgsign
; _chkesp ; _chkesp
; _chmod ; _chmod
; _chsize ; _chsize
; _clearfp _clearfp
_close _close
_commit _commit
_commode DATA _commode DATA
_control87 _control87
_controlfp _controlfp
; _copysign _copysign
; _cprintf ; _cprintf
; _cputs ; _cputs
; _creat ; _creat
@ -242,7 +242,7 @@ _finite
_flsbuf _flsbuf
_flushall _flushall
_fmode DATA _fmode DATA
; _fpclass _fpclass
_fpieee_flt _fpieee_flt
_fpreset _fpreset
; _fputchar ; _fputchar
@ -279,8 +279,8 @@ _global_unwind2
; _heapused ; _heapused
; _heapwalk ; _heapwalk
; _hypot ; _hypot
; _i64toa _i64toa
; _i64tow _i64tow
_initterm _initterm
; _inp ; _inp
; _inpd ; _inpd
@ -329,7 +329,7 @@ _loaddll
_local_unwind2 _local_unwind2
; _lock ; _lock
; _locking ; _locking
; _logb _logb
; _longjmpex ; _longjmpex
_lrotl _lrotl
_lrotr _lrotr
@ -399,7 +399,7 @@ _memicmp
_mkdir _mkdir
_mktemp _mktemp
; _msize ; _msize
; _nextafter _nextafter
_onexit _onexit
_open _open
_open_osfhandle _open_osfhandle
@ -427,7 +427,7 @@ _rotr
; _safe_fdivr ; _safe_fdivr
; _safe_fprem ; _safe_fprem
; _safe_fprem1 ; _safe_fprem1
; _scalb _scalb
_searchenv _searchenv
; _seh_longjmp_unwind ; _seh_longjmp_unwind
; _set_error_mode ; _set_error_mode
@ -454,7 +454,7 @@ _snwprintf
_splitpath _splitpath
_stat _stat
; _stati64 ; _stati64
; _statusfp _statusfp
_strcmpi _strcmpi
; _strdate ; _strdate
_strdup _strdup
@ -481,8 +481,8 @@ _tolower
_toupper _toupper
; _tzname ; _tzname
_tzset _tzset
; _ui64toa _ui64toa
; _ui64tow _ui64tow
_ultoa _ultoa
_ultow _ultow
; _umask ; _umask
@ -567,7 +567,7 @@ _wsplitpath
; _wtempnam ; _wtempnam
; _wtmpnam ; _wtmpnam
_wtoi _wtoi
; _wtoi64 _wtoi64
_wtol _wtol
; _wunlink ; _wunlink
; _wutime ; _wutime

View file

@ -0,0 +1,31 @@
#include <msvcrt/ctype.h>
#include <msvcrt/stdlib.h>
__int64
_atoi64(const char *nptr)
{
char *s = (char *)nptr;
__int64 acc = 0;
int neg = 0;
while(isspace((int)*s))
s++;
if (*s == '-')
{
neg = 1;
s++;
}
else if (*s == '+')
s++;
while (isdigit((int)*s))
{
acc = 10 * acc + ((int)*s - '0');
s++;
}
if (neg)
acc *= -1;
return acc;
}

View file

@ -131,4 +131,82 @@ _ultoa(unsigned long value, char *string, int radix)
*sp++ = *--tp; *sp++ = *--tp;
*sp = 0; *sp = 0;
return string; return string;
} }
char *
_i64toa(__int64 value, char *string, int radix)
{
char tmp[65];
char *tp = tmp;
int i;
unsigned v;
int sign;
char *sp;
if (radix > 36 || radix <= 1)
{
__set_errno(EDOM);
return 0;
}
sign = (radix == 10 && value < 0);
if (sign)
v = -value;
else
v = (unsigned)value;
while (v || tp == tmp)
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+'0';
else
*tp++ = i + 'a' - 10;
}
if (string == 0)
string = (char *)malloc((tp-tmp)+sign+1);
sp = string;
if (sign)
*sp++ = '-';
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;
return string;
}
char *
_ui64toa(unsigned __int64 value, char *string, int radix)
{
char tmp[65];
char *tp = tmp;
long i;
unsigned long v = value;
char *sp;
if (radix > 36 || radix <= 1)
{
__set_errno(EDOM);
return 0;
}
while (v || tp == tmp)
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+'0';
else
*tp++ = i + 'a' - 10;
}
if (string == 0)
string = (char *)malloc((tp-tmp)+1);
sp = string;
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;
return string;
}

View file

@ -55,7 +55,6 @@ _itow(int value, wchar_t *string, int radix)
return string; return string;
} }
wchar_t * wchar_t *
_ltow(long value, wchar_t *string, int radix) _ltow(long value, wchar_t *string, int radix)
{ {
@ -133,3 +132,81 @@ _ultow(unsigned long value, wchar_t *string, int radix)
*sp = 0; *sp = 0;
return string; return string;
} }
wchar_t *
_i64tow(__int64 value, wchar_t *string, int radix)
{
wchar_t tmp[65];
wchar_t *tp = tmp;
int i;
unsigned v;
int sign;
wchar_t *sp;
if (radix > 36 || radix <= 1)
{
__set_errno(EDOM);
return 0;
}
sign = (radix == 10 && value < 0);
if (sign)
v = -value;
else
v = (unsigned)value;
while (v || tp == tmp)
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+L'0';
else
*tp++ = i + L'a' - 10;
}
if (string == 0)
string = (wchar_t *)malloc(((tp-tmp)+sign+1)*sizeof(wchar_t));
sp = string;
if (sign)
*sp++ = L'-';
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;
return string;
}
wchar_t *
_ui64tow(unsigned __int64 value, wchar_t *string, int radix)
{
wchar_t tmp[65];
wchar_t *tp = tmp;
long i;
unsigned long v = value;
wchar_t *sp;
if (radix > 36 || radix <= 1)
{
__set_errno(EDOM);
return 0;
}
while (v || tp == tmp)
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+L'0';
else
*tp++ = i + L'a' - 10;
}
if (string == 0)
string = (wchar_t *)malloc(((tp-tmp)+1)*sizeof(wchar_t));
sp = string;
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;
return string;
}

View file

@ -0,0 +1,31 @@
#include <msvcrt/ctype.h>
#include <msvcrt/stdlib.h>
__int64
_wtoi64(const wchar_t *nptr)
{
wchar_t *s = (wchar_t *)nptr;
__int64 acc = 0;
int neg = 0;
while(iswspace((int)*s))
s++;
if (*s == '-')
{
neg = 1;
s++;
}
else if (*s == '+')
s++;
while (iswdigit((int)*s))
{
acc = 10 * acc + ((int)*s - '0');
s++;
}
if (neg)
acc *= -1;
return acc;
}