Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

297 lines
8.3 KiB

/***
*trans.h - definitions for computing transcendentals
*
* Copyright (c) 1991-1991, Microsoft Corporation. All rights reserved.
*
*Purpose: Define constants and macros that are used for computing
* transcendentals. Some of the definitions are machine dependent.
* Double is assumed to conform to the IEEE 754 std format.
*
*Revision History:
* 08-14-91 GDP written
* 10-29-91 GDP removed unused prototypes, added _frnd
* 01-20-92 GDP significant changes -- IEEE exc. support
* 03-27-92 GDP put IEEE definitions in fpieee.h
* 03-31-92 GDP add internal constants for _ctrlfp, _statfp
* 05-08-92 PLM added M68K switch
* 05-18-92 XY added exception macro under M68K switch
* 06-04-92 XY changed to long double version
*
*******************************************************************************/
#include <fpieee.h>
#define LD_BIASM1 0x3ffe /* LD_BIAS - 1 */
#ifdef B_END
/* big endian */
#define LD_EXP(x) ((unsigned short *)&(x))
#define LD_HI(x) ((unsigned long *)(&(x)+2))
#define LD_LO(x) ((unsigned long *)(&(x)+6))
#else
#define LD_EXP(x) ((unsigned short *)(&(x)+8))
#define LD_HI(x) ((unsigned long *)(&(x)+4))
#define LD_LO(x) ((unsigned long *)&(x))
#endif
/* return the int representation of the exponent
* if x = .f * 2^n, 0.5<=f<1, return n (unbiased)
* e.g. INTEXP(3.0) == 2
*/
#define INTEXPL(x) ((signed short)((*LD_EXP(x) & 0x7fff)) - LD_BIASM1)
/* check for infinity, NAN */
#define LD_ISINF(x) (( *LD_EXP(x) == 0x7fff) && *LD_HI(x) == 0 && *LD_LO(x) == 0)
#define IS_LD_SPECIAL(x) ((*LD_EXP(x) & 0x7fff) == 0x7fff)
#define IS_LD_NAN(x) (IS_LD_SPECIAL(x) && !LD_ISINF(x))
#define IS_LD_QNAN(x) ((*LD_EXP(x) & 0x7fff) == 0x7fff && (*LD_HI(x) == 0x80000000))
#define IS_LD_SNAN(x) ((*LD_EXP(x) & 0x7fff) == 0x7fff && \
(*LD_HI(x) && 0x80000000 == 0) && (*LD_HI(x) || *LD_LO(x)))
#define IS_LD_DENORM(x) ((*LD_EXP(x) & 0x7fff) == 0 && \
(*LD_HI(x) << 4 || *LD_LO(x)))
#define IS_LD_INF(x) (*LD_EXP(x) == 0x7fff && *LD_HI(x) == 0 && *LD_LO(x) == 0)
#define IS_LD_MINF(x) (*LD_EXP(x) == 0xffff && *LD_HI(x) == 0 && *LD_LO(x) == 0)
#ifdef MIPS
#define D_IND_HI 0x7ff7ffff
#define D_IND_LO 0xffffffff
#else
#define LD_IND_EXP 0xffff
#define LD_IND_HI 0x80000000
#define LD_IND_LO 0x0
#endif
typedef unsigned char u_char; /* should have 1 byte */
typedef union {
u_char lng[10];
long double ldbl;
} _ldbl;
extern _ldbl _ld_inf;
extern _ldbl _ld_ind;
extern _ldbl _ld_max;
extern _ldbl _ld_min;
#define LD_INF (_ld_inf.ldbl)
#define LD_IND (_ld_ind.ldbl)
#define LD_MAX (_ld_max.ldbl)
#define LD_MIN (_ld_min.ldbl)
/* min and max exponents for normalized numbers in the
* form: 0.xxxxx... * 2^exp (NOT 1.xxxx * 2^exp !)
*/
#define MAXEXP 32767
#define MINEXP -32764
#ifdef i386
/* Control word for computation of transcendentals */
#define ICW 0x133f
#define IMCW 0xffff
#define IMCW_EM 0x003f /* interrupt Exception Masks */
#define IEM_INVALID 0x0001 /* invalid */
#define IEM_DENORMAL 0x0002 /* denormal */
#define IEM_ZERODIVIDE 0x0004 /* zero divide */
#define IEM_OVERFLOW 0x0008 /* overflow */
#define IEM_UNDERFLOW 0x0010 /* underflow */
#define IEM_INEXACT 0x0020 /* inexact (precision) */
#define IMCW_RC 0x0c00 /* Rounding Control */
#define IRC_CHOP 0x0c00 /* chop */
#define IRC_UP 0x0800 /* up */
#define IRC_DOWN 0x0400 /* down */
#define IRC_NEAR 0x0000 /* near */
#define ISW_INVALID 0x0001 /* invalid */
#define ISW_DENORMAL 0x0002 /* denormal */
#define ISW_ZERODIVIDE 0x0004 /* zero divide */
#define ISW_OVERFLOW 0x0008 /* overflow */
#define ISW_UNDERFLOW 0x0010 /* underflow */
#define ISW_INEXACT 0x0020 /* inexact (precision) */
#define IMCW_PC 0x0300 /* Precision Control */
#define IPC_24 0x0000 /* 24 bits */
#define IPC_53 0x0200 /* 53 bits */
#define IPC_64 0x0300 /* 64 bits */
#define IMCW_IC 0x1000 /* Infinity Control */
#define IIC_AFFINE 0x1000 /* affine */
#define IIC_PROJECTIVE 0x0000 /* projective */
#endif
#ifdef MIPS
#define ICW 0x00000f80 /* Internal CW for transcendentals */
#define IMCW 0xffffff83 /* Internal CW Mask */
#define IMCW_EM 0x00000f80 /* interrupt Exception Masks */
#define IEM_INVALID 0x00000800 /* invalid */
#define IEM_ZERODIVIDE 0x00000400 /* zero divide */
#define IEM_OVERFLOW 0x00000200 /* overflow */
#define IEM_UNDERFLOW 0x00000100 /* underflow */
#define IEM_INEXACT 0x00000080 /* inexact (precision) */
#define IMCW_RC 0x00000003 /* Rounding Control */
#define IRC_CHOP 0x00000001 /* chop */
#define IRC_UP 0x00000002 /* up */
#define IRC_DOWN 0x00000003 /* down */
#define IRC_NEAR 0x00000000 /* near */
#define ISW_INVALID (1<<6) /* invalid */
#define ISW_ZERODIVIDE (1<<5) /* zero divide */
#define ISW_OVERFLOW (1<<4) /* overflow */
#define ISW_UNDERFLOW (1<<3) /* underflow */
#define ISW_INEXACT (1<<2) /* inexact (precision) */
#endif
#ifdef _M_M68K
#include "trans.a"
/* LATER -- we don't handle exception until Mac OS has better support on it */
#define _except1(FP_P, op, arg1, res, cw) _set_statfp(cw),(res)
#define _except2(FP_P, op, arg1, arg2, res, cw) _set_statfp(cw),(res)
#define _handle_qnan1(opcode, x, savedcw) _rstorfp(savedcw), (x);
#define _handle_qnan2(opcode, x, y, savedcw) _rstorfp(savedcw), (x+y);
#endif /* _M_M68K*/
#define RETURN(fpcw,result) return _rstorfp(fpcw),(result)
#define RETURN_INEXACT1(op,arg1,res,cw) \
if (cw & IEM_INEXACT) { \
_rstorfp(cw); \
return res; \
} \
else { \
return _except1(FP_P, op, arg1, res, cw); \
}
#define RETURN_INEXACT2(op,arg1,arg2,res,cw) \
if (cw & IEM_INEXACT) { \
_rstorfp(cw); \
return res; \
} \
else { \
return _except2(FP_P, op, arg1, arg2, res, cw); \
}
//handle NaN propagation
#define _d_snan2(x,y) ((x)+(y))
#define _s2qnan(x) ((x)+1.0)
#define _maskfp() _ctrlfp(ICW, IMCW)
#define _rstorfp(cw) _ctrlfp(cw, IMCW)
#define ABS(x) ((x)<0 ? -(x) : (x) )
int _d_inttypel(long double);
#define _D_NOINT 0
#define _D_ODD 1
#define _D_EVEN 2
// IEEE exceptions
#define FP_O 0x01
#define FP_U 0x02
#define FP_Z 0x04
#define FP_I 0x08
#define FP_P 0x10
// An extra flag for matherr support
// Set together with FP_I from trig functions when the argument is too large
#define FP_TLOSS 0x20
// special types
#define T_PINF 1
#define T_NINF 2
#define T_QNAN 3
#define T_SNAN 4
// exponent adjustment for IEEE overflow/underflow exceptions
// used before passing the result to the trap handler
#define IEEE_ADJUST 1536
// QNAN values
#define INT_NAN (~0)
#define QNAN_SQRT LD_IND
#define QNAN_LOG LD_IND
#define QNAN_LOG10 LD_IND
#define QNAN_POW LD_IND
#define QNAN_SINH LD_IND
#define QNAN_COSH LD_IND
#define QNAN_TANH LD_IND
#define QNAN_SIN1 LD_IND
#define QNAN_SIN2 LD_IND
#define QNAN_COS1 LD_IND
#define QNAN_COS2 LD_IND
#define QNAN_TAN1 LD_IND
#define QNAN_TAN2 LD_IND
#define QNAN_ACOS LD_IND
#define QNAN_ASIN LD_IND
#define QNAN_ATAN2 LD_IND
#define QNAN_CEIL LD_IND
#define QNAN_FLOOR LD_IND
#define QNAN_MODF LD_IND
#define QNAN_LDEXP LD_IND
#define QNAN_FMOD LD_IND
#define QNAN_FREXP LD_IND
/*
* Function prototypes
*/
long double _set_expl(long double x, int exp);
long double _set_bexpl(long double x, int exp);
long double _add_expl(long double x, int exp);
long double _frndl(long double);
long double _fsqrtl(long double);
#ifndef _M_M68K
double _except1(int flags, int opcode, double arg, double res, unsigned int cw);
double _except2(int flags, int opcode, double arg1, double arg2, double res, unsigned int cw);
#endif
int _sptypel(long double);
int _get_expl(long double);
long double _decompl(long double, int *);
int _powhlpl(long double x, long double y, long double * result);
extern unsigned int _fpstatus;
long double _frndl(long double);
long double _exphlpl(long double, int *);
#ifndef _M_M68K
double _handle_qnan1(unsigned int op, double arg, unsigned int cw);
double _handle_qnan2(unsigned int op,double arg1,double arg2,unsigned int cw);
#endif
unsigned int _clhwfp(void);
unsigned int _setfpcw(unsigned int);
int _errcode(unsigned int flags);
void _set_errno(int matherrtype);
int _handle_excl(unsigned int flags, long double * presult, unsigned int cw);
unsigned int _clrfp(void);
unsigned int _ctrlfp(unsigned int,unsigned int);
unsigned int _statfp(void);
#ifdef _M_M68K
void _set_statfp(unsigned int sw);
#endif