Leaked source code of windows server 2003
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.

586 lines
17 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. trans.h
  5. Abstract:
  6. Header file for math functions.
  7. Author:
  8. Revision History:
  9. 29-sept-1999 ATM Shafiqul Khalid [askhalid] copied from rtl library.
  10. --*/
  11. #ifndef _INC_TRANS
  12. #ifdef __cplusplus
  13. extern "C" {
  14. #endif
  15. #ifndef __assembler /* MIPS ONLY: Protect from assembler */
  16. //#include <cruntime.h>
  17. void
  18. SetMathError (
  19. int Code
  20. );
  21. #define OP_UNSPEC 0
  22. #define OP_ADD 1
  23. #define OP_SUB 2
  24. #define OP_MUL 3
  25. #define OP_DIV 4
  26. #define OP_SQRT 5
  27. #define OP_REM 6
  28. #define OP_COMP 7
  29. #define OP_CVT 8
  30. #define OP_RND 9
  31. #define OP_TRUNC 10
  32. #define OP_FLOOR 11
  33. #define OP_CEIL 12
  34. #define OP_ACOS 13
  35. #define OP_ASIN 14
  36. #define OP_ATAN 15
  37. #define OP_ATAN2 16
  38. #define OP_CABS 17
  39. #define OP_COS 18
  40. #define OP_COSH 19
  41. #define OP_EXP 20
  42. #define OP_ABS 21 /* same as OP_FABS */
  43. #define OP_FABS 21 /* same as OP_ABS */
  44. #define OP_FMOD 22
  45. #define OP_FREXP 23
  46. #define OP_HYPOT 24
  47. #define OP_LDEXP 25
  48. #define OP_LOG 26
  49. #define OP_LOG10 27
  50. #define OP_MODF 28
  51. #define OP_POW 29
  52. #define OP_SIN 30
  53. #define OP_SINH 31
  54. #define OP_TAN 32
  55. #define OP_TANH 33
  56. #define OP_Y0 34
  57. #define OP_Y1 35
  58. #define OP_YN 36
  59. #define OP_LOGB 37
  60. #define OP_NEXTAFTER 38
  61. #define OP_NEG 39
  62. /* Define __cdecl for non-Microsoft compilers */
  63. #if ( !defined(_MSC_VER) && !defined(__cdecl) )
  64. #define __cdecl
  65. #endif
  66. #include <fpieee.h>
  67. #define D_BIASM1 0x3fe /* off by one to compensate for the implied bit */
  68. #ifdef B_END
  69. /* big endian */
  70. #define D_EXP(x) ((unsigned short *)&(x))
  71. #define D_HI(x) ((unsigned long *)&(x))
  72. #define D_LO(x) ((unsigned long *)&(x)+1)
  73. #else
  74. #define D_EXP(x) ((unsigned short *)&(x)+3)
  75. #define D_HI(x) ((unsigned long *)&(x)+1)
  76. #define D_LO(x) ((unsigned long *)&(x))
  77. #endif
  78. /* return the int representation of the exponent
  79. * if x = .f * 2^n, 0.5<=f<1, return n (unbiased)
  80. * e.g. INTEXP(3.0) == 2
  81. */
  82. #define INTEXP(x) ((signed short)((*D_EXP(x) & 0x7ff0) >> 4) - D_BIASM1)
  83. /* check for infinity, NAN */
  84. #define D_ISINF(x) ((*D_HI(x) & 0x7fffffff) == 0x7ff00000 && *D_LO(x) == 0)
  85. #define IS_D_SPECIAL(x) ((*D_EXP(x) & 0x7ff0) == 0x7ff0)
  86. #define IS_D_NAN(x) (IS_D_SPECIAL(x) && !D_ISINF(x))
  87. #ifdef _M_MRX000
  88. #define IS_D_SNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff8)
  89. #define IS_D_QNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff0 && \
  90. (*D_HI(x) << 13 || *D_LO(x)))
  91. #else
  92. #define IS_D_QNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff8)
  93. #define IS_D_SNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff0 && \
  94. (*D_HI(x) << 13 || *D_LO(x)))
  95. #endif
  96. #define IS_D_DENORM(x) ((*D_EXP(x) & 0x7ff0) == 0 && \
  97. (*D_HI(x) << 12 || *D_LO(x)))
  98. #define IS_D_INF(x) (*D_HI(x) == 0x7ff00000 && *D_LO(x) == 0)
  99. #define IS_D_MINF(x) (*D_HI(x) == 0xfff00000 && *D_LO(x) == 0)
  100. #ifdef _M_MRX000
  101. #define D_IND_HI 0x7ff7ffff
  102. #define D_IND_LO 0xffffffff
  103. #else
  104. #define D_IND_HI 0xfff80000
  105. #define D_IND_LO 0x0
  106. #endif
  107. typedef union {
  108. long lng[2];
  109. double dbl;
  110. } _dbl;
  111. #ifndef DEFINE_EXTERN_HERE
  112. extern _dbl _d_inf;
  113. extern _dbl _d_ind;
  114. extern _dbl _d_max;
  115. extern _dbl _d_min;
  116. extern _dbl _d_mzero;
  117. #else
  118. _dbl _d_inf;
  119. _dbl _d_ind;
  120. _dbl _d_max;
  121. _dbl _d_min;
  122. _dbl _d_mzero;
  123. #endif
  124. #define D_INF (_d_inf.dbl)
  125. #define D_IND (_d_ind.dbl)
  126. #define D_MAX (_d_max.dbl)
  127. #define D_MIN (_d_min.dbl)
  128. #define D_MZERO (_d_mzero.dbl) /* minus zero */
  129. /* min and max exponents for normalized numbers in the
  130. * form: 0.xxxxx... * 2^exp (NOT 1.xxxx * 2^exp !)
  131. */
  132. #define MAXEXP 1024
  133. #define MINEXP -1021
  134. #endif /* #ifndef __assembler */
  135. #if defined(_M_IX86)
  136. /* Control word for computation of transcendentals */
  137. #define ICW 0x133f
  138. #define IMCW 0xffff
  139. #define IMCW_EM 0x003f /* interrupt Exception Masks */
  140. #define IEM_INVALID 0x0001 /* invalid */
  141. #define IEM_DENORMAL 0x0002 /* denormal */
  142. #define IEM_ZERODIVIDE 0x0004 /* zero divide */
  143. #define IEM_OVERFLOW 0x0008 /* overflow */
  144. #define IEM_UNDERFLOW 0x0010 /* underflow */
  145. #define IEM_INEXACT 0x0020 /* inexact (precision) */
  146. #define IMCW_RC 0x0c00 /* Rounding Control */
  147. #define IRC_CHOP 0x0c00 /* chop */
  148. #define IRC_UP 0x0800 /* up */
  149. #define IRC_DOWN 0x0400 /* down */
  150. #define IRC_NEAR 0x0000 /* near */
  151. #define ISW_INVALID 0x0001 /* invalid */
  152. #define ISW_DENORMAL 0x0002 /* denormal */
  153. #define ISW_ZERODIVIDE 0x0004 /* zero divide */
  154. #define ISW_OVERFLOW 0x0008 /* overflow */
  155. #define ISW_UNDERFLOW 0x0010 /* underflow */
  156. #define ISW_INEXACT 0x0020 /* inexact (precision) */
  157. #define IMCW_PC 0x0300 /* Precision Control */
  158. #define IPC_24 0x0000 /* 24 bits */
  159. #define IPC_53 0x0200 /* 53 bits */
  160. #define IPC_64 0x0300 /* 64 bits */
  161. #define IMCW_IC 0x1000 /* Infinity Control */
  162. #define IIC_AFFINE 0x1000 /* affine */
  163. #define IIC_PROJECTIVE 0x0000 /* projective */
  164. #elif defined(_M_MRX000)
  165. #define ICW 0x00000f80 /* Internal CW for transcendentals */
  166. #define IMCW 0xffffff83 /* Internal CW Mask */
  167. #define IMCW_EM 0x00000f80 /* interrupt Exception Masks */
  168. #define IEM_INVALID 0x00000800 /* invalid */
  169. #define IEM_ZERODIVIDE 0x00000400 /* zero divide */
  170. #define IEM_OVERFLOW 0x00000200 /* overflow */
  171. #define IEM_UNDERFLOW 0x00000100 /* underflow */
  172. #define IEM_INEXACT 0x00000080 /* inexact (precision) */
  173. #define IMCW_RC 0x00000003 /* Rounding Control */
  174. #define IRC_CHOP 0x00000001 /* chop */
  175. #define IRC_UP 0x00000002 /* up */
  176. #define IRC_DOWN 0x00000003 /* down */
  177. #define IRC_NEAR 0x00000000 /* near */
  178. #define ISW_INVALID (1<<6) /* invalid */
  179. #define ISW_ZERODIVIDE (1<<5) /* zero divide */
  180. #define ISW_OVERFLOW (1<<4) /* overflow */
  181. #define ISW_UNDERFLOW (1<<3) /* underflow */
  182. #define ISW_INEXACT (1<<2) /* inexact (precision) */
  183. #elif defined(_M_ALPHA)
  184. //
  185. // ICW is the Internal Control Word for transcendentals: all five exceptions
  186. // are masked and round to nearest mode is set. IMCW is the mask: all bits
  187. // are set, except for the ISW bits.
  188. //
  189. #define ICW (IEM_INEXACT | IEM_UNDERFLOW | IEM_OVERFLOW | IEM_ZERODIVIDE | IEM_INVALID | IRC_NEAR)
  190. #define ISW (ISW_INEXACT | ISW_UNDERFLOW | ISW_OVERFLOW | ISW_ZERODIVIDE | ISW_INVALID)
  191. #define IMCW (0xffffffff ^ ISW)
  192. //
  193. // The defines for the internal control word match the format of the Alpha
  194. // AXP software FPCR except for the rounding mode which is obtained from the
  195. // Alpha AXP hardware FPCR and shifted right 32 bits.
  196. //
  197. //
  198. // Internal Exception Mask bits.
  199. // Each bit _disables_ an exception (they are not _enable_ bits).
  200. //
  201. #define IMCW_EM 0x0000003e /* interrupt Exception Masks */
  202. #define IEM_INEXACT 0x00000020 /* inexact (precision) */
  203. #define IEM_UNDERFLOW 0x00000010 /* underflow */
  204. #define IEM_OVERFLOW 0x00000008 /* overflow */
  205. #define IEM_ZERODIVIDE 0x00000004 /* zero divide */
  206. #define IEM_INVALID 0x00000002 /* invalid */
  207. //
  208. // Internal Rounding Control values.
  209. //
  210. #define IMCW_RC (0x3 << 26) /* Rounding Control */
  211. #define IRC_CHOP (0x0 << 26) /* chop */
  212. #define IRC_DOWN (0x1 << 26) /* down */
  213. #define IRC_NEAR (0x2 << 26) /* near */
  214. #define IRC_UP (0x3 << 26) /* up */
  215. //
  216. // Internal Status Word bits.
  217. //
  218. #define ISW_INEXACT 0x00200000 /* inexact (precision) */
  219. #define ISW_UNDERFLOW 0x00100000 /* underflow */
  220. #define ISW_OVERFLOW 0x00080000 /* overflow */
  221. #define ISW_ZERODIVIDE 0x00040000 /* zero divide */
  222. #define ISW_INVALID 0x00020000 /* invalid */
  223. #elif defined(_M_PPC)
  224. #define IMCW_EM 0x000000f8 /* Exception Enable Mask */
  225. #define IEM_INVALID 0x00000080 /* invalid */
  226. #define IEM_OVERFLOW 0x00000040 /* overflow */
  227. #define IEM_UNDERFLOW 0x00000020 /* underflow */
  228. #define IEM_ZERODIVIDE 0x00000010 /* zero divide */
  229. #define IEM_INEXACT 0x00000008 /* inexact (precision) */
  230. #define IMCW_RC 0x00000003 /* Rounding Control Mask */
  231. #define IRC_NEAR 0x00000000 /* near */
  232. #define IRC_CHOP 0x00000001 /* chop */
  233. #define IRC_UP 0x00000002 /* up */
  234. #define IRC_DOWN 0x00000003 /* down */
  235. #define IMCW_SW 0x3E000000 /* Status Mask */
  236. #define ISW_INVALID 0x20000000 /* invalid summary */
  237. #define ISW_OVERFLOW 0x10000000 /* overflow */
  238. #define ISW_UNDERFLOW 0x08000000 /* underflow */
  239. #define ISW_ZERODIVIDE 0x04000000 /* zero divide */
  240. #define ISW_INEXACT 0x02000000 /* inexact (precision) */
  241. #define IMCW_VX 0x01F80700 /* Invalid Cause Mask */
  242. #define IVX_SNAN 0x01000000 /* SNaN */
  243. #define IVX_ISI 0x00800000 /* infinity - infinity */
  244. #define IVX_IDI 0x00400000 /* infinity / infinity */
  245. #define IVX_ZDZ 0x00200000 /* zero / zero */
  246. #define IVX_IMZ 0x00100000 /* infinity * zero */
  247. #define IVX_VC 0x00080000 /* inv flpt compare */
  248. #define IVX_SOFT 0x00000400 /* software request */
  249. #define IVX_SQRT 0x00000200 /* sqrt of negative */
  250. #define IVX_CVI 0x00000100 /* inv integer convert */
  251. /* Internal CW for transcendentals */
  252. #define ICW (IMCW_EM)
  253. /* Internal CW Mask (non-status bits) */
  254. #define IMCW (0xffffffff & (~(IMCW_SW|IMCW_VX)))
  255. #elif defined(_M_M68K)
  256. #include "mac\m68k\trans.a"
  257. /* LATER -- we don't handle exception until Mac OS has better support on it */
  258. #define _except1(flags, op, arg1, res, cw) _errcode(flags), _rstorfp(cw), \
  259. _set_statfp(cw),(res)
  260. #define _except2(flags, op, arg1, arg2, res, cw) _errcode(flags), _rstorfp(cw), \
  261. _set_statfp(cw),(res)
  262. #define _handle_qnan1(opcode, x, savedcw) _set_errno(_DOMAIN), _rstorfp(savedcw), (x);
  263. #define _handle_qnan2(opcode, x, y, savedcw) _set_errno(_DOMAIN), _rstorfp(savedcw), (x+y);
  264. #elif defined(_M_MPPC)
  265. /* Mac control information - included as part of trans.h
  266. It is broken out to allow use with ASM68 files*/
  267. /* Control word for computation of transcendentals */
  268. #define ICW (IPC_64 + IRC_NEAR + IMCW_EM)
  269. #define IMCW IMCW_RC + IMCW_PC
  270. #define IMCW_EM 0x000000f8 /* interrupt Exception Masks */
  271. #define IEM_INVALID 0x00000080 /* invalid */
  272. #define IEM_ZERODIVIDE 0x00000010 /* zero divide */
  273. #define IEM_OVERFLOW 0x00000040 /* overflow */
  274. #define IEM_UNDERFLOW 0x00000020 /* underflow */
  275. #define IEM_INEXACT 0x00000008 /* inexact (precision) */
  276. #define IMCW_RC 0x00000003 /* Rounding Control */
  277. #define IRC_CHOP 0x00000001 /* chop */
  278. #define IRC_UP 0x00000002 /* up */
  279. #define IRC_DOWN 0x00000003 /* down */
  280. #define IRC_NEAR 0x00000000 /* near */
  281. #define IMSW 0xffffff00 /* status bits mask */
  282. #define ISW_INVALID 0x20000000 /* invalid */
  283. #define ISW_ZERODIVIDE 0x04000000 /* zero divide */
  284. #define ISW_OVERFLOW 0x10000000 /* overflow */
  285. #define ISW_UNDERFLOW 0x08000000 /* underflow */
  286. #define ISW_INEXACT 0x02000000 /* inexact (precision) */
  287. #define IMCW_PC 0x0000 /* Precision Control */
  288. #define IPC_24 0x0000 /* 24 bits */
  289. #define IPC_53 0x0000 /* 53 bits */
  290. #define IPC_64 0x0000 /* 64 bits */
  291. /* LATER -- we don't handle exception until Mac OS has better support on it */
  292. #define _except1(flags, op, arg1, res, cw) _errcode(flags), \
  293. _set_statfp(cw),(res)
  294. #define _except2(flags, op, arg1, arg2, res, cw) _errcode(flags), \
  295. _set_statfp(cw),(res)
  296. #define _handle_qnan1(opcode, x, savedcw) _set_errno(_DOMAIN), _rstorfp(savedcw), (x);
  297. #define _handle_qnan2(opcode, x, y, savedcw) _set_errno(_DOMAIN), _rstorfp(savedcw), (x+y);
  298. #endif
  299. #ifndef __assembler /* MIPS ONLY: Protect from assembler */
  300. #define RETURN(fpcw,result) return _rstorfp(fpcw),(result)
  301. #define RETURN_INEXACT1(op,arg1,res,cw) \
  302. if (cw & IEM_INEXACT) { \
  303. _rstorfp(cw); \
  304. return res; \
  305. } \
  306. else { \
  307. return _except1(FP_P, op, arg1, res, cw); \
  308. }
  309. #define RETURN_INEXACT2(op,arg1,arg2,res,cw) \
  310. if (cw & IEM_INEXACT) { \
  311. _rstorfp(cw); \
  312. return res; \
  313. } \
  314. else { \
  315. return _except2(FP_P, op, arg1, arg2, res, cw); \
  316. }
  317. #ifdef _M_ALPHA
  318. //
  319. // Since fp32 is not compiled in IEEE exception mode perform Alpha NaN
  320. // propagation in software to avoid hardware/kernel trap involvement.
  321. //
  322. extern double _nan2qnan(double);
  323. #define _d_snan2(x,y) _nan2qnan(y)
  324. #define _s2qnan(x) _nan2qnan(x)
  325. #else
  326. //handle NaN propagation
  327. #define _d_snan2(x,y) ((x)+(y))
  328. #define _s2qnan(x) ((x)+1.0)
  329. #endif
  330. #define _maskfp() _ctrlfp(ICW, IMCW)
  331. #ifdef _M_ALPHA
  332. #define _rstorfp(cw) 0
  333. #else
  334. #define _rstorfp(cw) _ctrlfp(cw, IMCW)
  335. #endif
  336. #define ABS(x) ((x)<0 ? -(x) : (x) )
  337. int _d_inttype(double);
  338. #endif /* #ifndef __assembler */
  339. #define _D_NOINT 0
  340. #define _D_ODD 1
  341. #define _D_EVEN 2
  342. // IEEE exceptions
  343. #define FP_O 0x01
  344. #define FP_U 0x02
  345. #define FP_Z 0x04
  346. #define FP_I 0x08
  347. #define FP_P 0x10
  348. // An extra flag for matherr support
  349. // Set together with FP_I from trig functions when the argument is too large
  350. #define FP_TLOSS 0x20
  351. #ifndef __assembler /* MIPS ONLY: Protect from assembler */
  352. #ifdef B_END
  353. #define SET_DBL(msw, lsw) msw, lsw
  354. #else
  355. #define SET_DBL(msw, lsw) lsw, msw
  356. #endif
  357. #endif /* #ifndef __assembler */
  358. // special types
  359. #define T_PINF 1
  360. #define T_NINF 2
  361. #define T_QNAN 3
  362. #define T_SNAN 4
  363. // exponent adjustment for IEEE overflow/underflow exceptions
  364. // used before passing the result to the trap handler
  365. #define IEEE_ADJUST 1536
  366. // QNAN values
  367. #define INT_NAN (~0)
  368. #define QNAN_SQRT D_IND
  369. #define QNAN_LOG D_IND
  370. #define QNAN_LOG10 D_IND
  371. #define QNAN_POW D_IND
  372. #define QNAN_SINH D_IND
  373. #define QNAN_COSH D_IND
  374. #define QNAN_TANH D_IND
  375. #define QNAN_SIN1 D_IND
  376. #define QNAN_SIN2 D_IND
  377. #define QNAN_COS1 D_IND
  378. #define QNAN_COS2 D_IND
  379. #define QNAN_TAN1 D_IND
  380. #define QNAN_TAN2 D_IND
  381. #define QNAN_ACOS D_IND
  382. #define QNAN_ASIN D_IND
  383. #define QNAN_ATAN2 D_IND
  384. #define QNAN_CEIL D_IND
  385. #define QNAN_FLOOR D_IND
  386. #define QNAN_MODF D_IND
  387. #define QNAN_LDEXP D_IND
  388. #define QNAN_FMOD D_IND
  389. #define QNAN_FREXP D_IND
  390. /*
  391. * Function prototypes
  392. */
  393. #ifndef __assembler /* MIPS ONLY: Protect from assembler */
  394. double _set_exp(double x, int exp);
  395. double _set_bexp(double x, int exp);
  396. double _add_exp(double x, int exp);
  397. double _frnd(double);
  398. double _fsqrt(double);
  399. #if !defined(_M_M68K) && !defined(_M_MPPC)
  400. double _except1(int flags, int opcode, double arg, double res, unsigned int cw);
  401. double _except2(int flags, int opcode, double arg1, double arg2, double res, unsigned int cw);
  402. #endif
  403. int _sptype(double);
  404. int _get_exp(double);
  405. double _decomp(double, int *);
  406. int _powhlp(double x, double y, double * result);
  407. extern unsigned int _fpstatus;
  408. double _frnd(double);
  409. double _exphlp(double, int *);
  410. #if !defined(_M_M68K) && !defined(_M_MPPC)
  411. double _handle_qnan1(unsigned int op, double arg, unsigned int cw);
  412. double _handle_qnan2(unsigned int op,double arg1,double arg2,unsigned int cw);
  413. #endif
  414. unsigned int _clhwfp(void);
  415. unsigned int _setfpcw(unsigned int);
  416. int _errcode(unsigned int flags);
  417. void _set_errno(int matherrtype);
  418. int _handle_exc(unsigned int flags, double * presult, unsigned int cw);
  419. unsigned int _clrfp(void);
  420. unsigned int _ctrlfp(unsigned int,unsigned int);
  421. unsigned int _statfp(void);
  422. void _set_statfp(unsigned int);
  423. #endif /* #ifndef __assembler */
  424. #ifdef __cplusplus
  425. }
  426. #endif
  427. #define _INC_TRANS
  428. #endif /* _INC_TRANS */