Source code of Windows XP (NT5)
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.

565 lines
18 KiB

  1. /***
  2. *trans.h - definitions for computing transcendentals
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Define constants and macros that are used for computing
  8. * transcendentals. Some of the definitions are machine dependent.
  9. * Double is assumed to conform to the IEEE 754 std format.
  10. *
  11. *Revision History:
  12. * 08-14-91 GDP written
  13. * 10-29-91 GDP removed unused prototypes, added _frnd
  14. * 01-20-92 GDP significant changes -- IEEE exc. support
  15. * 03-27-92 GDP put IEEE definitions in fpieee.h
  16. * 03-31-92 GDP add internal constants for _ctrlfp, _statfp
  17. * 05-08-92 PLM added M68K switch
  18. * 05-18-92 XY added exception macro under M68K switch
  19. * 06-23-92 GDP added macro for negative zero
  20. * 09-06-92 GDP include cruntime.h, calling convention macros
  21. * 07-16-93 SRW ALPHA Merge
  22. * 11-17-93 GJF Merged in NT SDK version. Replaced MIPS with
  23. * _M_MRX000, _ALPHA_ with _M_ALPHA, deleted old M68K
  24. * stuff (obsolete).
  25. * 01-13-94 RDL Added #ifndef _LANGUAGE_ASSEMBLY for asm includes.
  26. * 01-25-94 GJF Merged in 01-13 change above from Roger Lanser (from
  27. * fp32 tree on \\orville\razzle).
  28. * 03-11-94 GJF Picked up latest changes from Dec (from fp32 tree
  29. * on \\orville\razzle for Alpha build).
  30. * 10-02-94 BWT PPC merge
  31. * 02-06-95 JWM Mac merge
  32. * 02-07-95 JWM powhlp() prototype restored to Intel version.
  33. * 10-07-97 RDL Added IA64.
  34. * 05-13-99 PML Remove _CRTAPI1
  35. * 05-17-99 PML Remove all Macintosh support.
  36. * 10-06-99 PML Add _W64 modifier to types which are 32 bits in Win32,
  37. * 64 bits in Win64.
  38. * 04-30-01 BWT AMD64 change from DaveC
  39. *
  40. *******************************************************************************/
  41. #ifndef _INC_TRANS
  42. #ifdef __cplusplus
  43. extern "C" {
  44. #endif
  45. #ifndef __assembler /* MIPS ONLY: Protect from assembler */
  46. #include <cruntime.h>
  47. /* Define __cdecl for non-Microsoft compilers */
  48. #if ( !defined(_MSC_VER) && !defined(__cdecl) )
  49. #define __cdecl
  50. #endif
  51. #if !defined(_W64)
  52. #if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
  53. #define _W64 __w64
  54. #else
  55. #define _W64
  56. #endif
  57. #endif
  58. #ifndef _INTPTR_T_DEFINED
  59. #ifdef _WIN64
  60. typedef __int64 intptr_t;
  61. #else
  62. typedef _W64 int intptr_t;
  63. #endif
  64. #define _INTPTR_T_DEFINED
  65. #endif
  66. #ifndef _UINTPTR_T_DEFINED
  67. #ifdef _WIN64
  68. typedef unsigned __int64 uintptr_t;
  69. #else
  70. typedef _W64 unsigned int uintptr_t;
  71. #endif
  72. #define _UINTPTR_T_DEFINED
  73. #endif
  74. #include <fpieee.h>
  75. #define D_BIASM1 0x3fe /* off by one to compensate for the implied bit */
  76. #ifdef B_END
  77. /* big endian */
  78. #define D_EXP(x) ((unsigned short *)&(x))
  79. #define D_HI(x) ((unsigned long *)&(x))
  80. #define D_LO(x) ((unsigned long *)&(x)+1)
  81. #else
  82. #define D_EXP(x) ((unsigned short *)&(x)+3)
  83. #define D_HI(x) ((unsigned long *)&(x)+1)
  84. #define D_LO(x) ((unsigned long *)&(x))
  85. #endif
  86. /* return the int representation of the exponent
  87. * if x = .f * 2^n, 0.5<=f<1, return n (unbiased)
  88. * e.g. INTEXP(3.0) == 2
  89. */
  90. #define INTEXP(x) ((signed short)((*D_EXP(x) & 0x7ff0) >> 4) - D_BIASM1)
  91. /* check for infinity, NAN */
  92. #define D_ISINF(x) ((*D_HI(x) & 0x7fffffff) == 0x7ff00000 && *D_LO(x) == 0)
  93. #define IS_D_SPECIAL(x) ((*D_EXP(x) & 0x7ff0) == 0x7ff0)
  94. #define IS_D_NAN(x) (IS_D_SPECIAL(x) && !D_ISINF(x))
  95. #ifdef _M_MRX000
  96. #define IS_D_SNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff8)
  97. #define IS_D_QNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff0 && \
  98. (*D_HI(x) << 13 || *D_LO(x)))
  99. #else
  100. #define IS_D_QNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff8)
  101. #define IS_D_SNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff0 && \
  102. (*D_HI(x) << 13 || *D_LO(x)))
  103. #endif
  104. #define IS_D_DENORM(x) ((*D_EXP(x) & 0x7ff0) == 0 && \
  105. (*D_HI(x) << 12 || *D_LO(x)))
  106. #define IS_D_INF(x) (*D_HI(x) == 0x7ff00000 && *D_LO(x) == 0)
  107. #define IS_D_MINF(x) (*D_HI(x) == 0xfff00000 && *D_LO(x) == 0)
  108. #ifdef _M_MRX000
  109. #define D_IND_HI 0x7ff7ffff
  110. #define D_IND_LO 0xffffffff
  111. #else
  112. #define D_IND_HI 0xfff80000
  113. #define D_IND_LO 0x0
  114. #endif
  115. typedef union {
  116. long lng[2];
  117. double dbl;
  118. } _dbl;
  119. extern _dbl _d_inf;
  120. extern _dbl _d_ind;
  121. extern _dbl _d_max;
  122. extern _dbl _d_min;
  123. extern _dbl _d_mzero;
  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_AMD64)
  165. /* Control word for computation of transcendentals */
  166. #define ICW (IMCW_EM | IRC_NEAR)
  167. #define ISW (ISW_INEXACT | ISW_UNDERFLOW | ISW_OVERFLOW | ISW_ZERODIVIDE | ISW_INVALID | ISW_DENORMAL)
  168. #define IMCW (0xffff ^ ISW)
  169. #define IMCW_EM 0x1f80 /* interrupt Exception Masks */
  170. #define IEM_INVALID 0x0080 /* invalid */
  171. #define IEM_DENORMAL 0x0100 /* denormal */
  172. #define IEM_ZERODIVIDE 0x0200 /* zero divide */
  173. #define IEM_OVERFLOW 0x0400 /* overflow */
  174. #define IEM_UNDERFLOW 0x0800 /* underflow */
  175. #define IEM_INEXACT 0x1000 /* inexact (precision) */
  176. #define IMCW_RC 0x6000 /* Rounding Control */
  177. #define IRC_CHOP 0x6000 /* chop */
  178. #define IRC_UP 0x4000 /* up */
  179. #define IRC_DOWN 0x2000 /* down */
  180. #define IRC_NEAR 0x0000 /* near */
  181. #define ISW_INVALID 0x0001 /* invalid */
  182. #define ISW_DENORMAL 0x0002 /* denormal */
  183. #define ISW_ZERODIVIDE 0x0004 /* zero divide */
  184. #define ISW_OVERFLOW 0x0008 /* overflow */
  185. #define ISW_UNDERFLOW 0x0010 /* underflow */
  186. #define ISW_INEXACT 0x0020 /* inexact (precision) */
  187. #elif defined(_M_IA64)
  188. /* Control word for computation of transcendentals */
  189. #define ICW (IMCW_EM | IRC_NEAR | IPC_64)
  190. #define ISW (ISW_INEXACT | ISW_UNDERFLOW | ISW_OVERFLOW | ISW_ZERODIVIDE | ISW_INVALID | ISW_DENORMAL)
  191. #define IMCW (0xffffffff ^ ISW)
  192. #define IMCW_EM 0x003f /* interrupt Exception Masks */
  193. #define IEM_INVALID 0x0001 /* invalid */
  194. #define IEM_DENORMAL 0x0002 /* denormal */
  195. #define IEM_ZERODIVIDE 0x0004 /* zero divide */
  196. #define IEM_OVERFLOW 0x0008 /* overflow */
  197. #define IEM_UNDERFLOW 0x0010 /* underflow */
  198. #define IEM_INEXACT 0x0020 /* inexact (precision) */
  199. #define IMCW_RC 0x0c00 /* Rounding Control */
  200. #define IRC_CHOP 0x0c00 /* chop */
  201. #define IRC_UP 0x0800 /* up */
  202. #define IRC_DOWN 0x0400 /* down */
  203. #define IRC_NEAR 0x0000 /* near */
  204. #define ISW_INVALID 0x02000 /* invalid */
  205. #define ISW_DENORMAL 0x04000 /* denormal */
  206. #define ISW_ZERODIVIDE 0x08000 /* zero divide */
  207. #define ISW_OVERFLOW 0x10000 /* overflow */
  208. #define ISW_UNDERFLOW 0x20000 /* underflow */
  209. #define ISW_INEXACT 0x40000 /* inexact (precision) */
  210. #define IMCW_PC 0x0300 /* Precision Control */
  211. #define IPC_24 0x0000 /* 24 bits */
  212. #define IPC_53 0x0200 /* 53 bits */
  213. #define IPC_64 0x0300 /* 64 bits */
  214. #elif defined(_M_MRX000)
  215. #define ICW 0x00000f80 /* Internal CW for transcendentals */
  216. #define IMCW 0xffffff83 /* Internal CW Mask */
  217. #define IMCW_EM 0x00000f80 /* interrupt Exception Masks */
  218. #define IEM_INVALID 0x00000800 /* invalid */
  219. #define IEM_ZERODIVIDE 0x00000400 /* zero divide */
  220. #define IEM_OVERFLOW 0x00000200 /* overflow */
  221. #define IEM_UNDERFLOW 0x00000100 /* underflow */
  222. #define IEM_INEXACT 0x00000080 /* inexact (precision) */
  223. #define IMCW_RC 0x00000003 /* Rounding Control */
  224. #define IRC_CHOP 0x00000001 /* chop */
  225. #define IRC_UP 0x00000002 /* up */
  226. #define IRC_DOWN 0x00000003 /* down */
  227. #define IRC_NEAR 0x00000000 /* near */
  228. #define ISW_INVALID (1<<6) /* invalid */
  229. #define ISW_ZERODIVIDE (1<<5) /* zero divide */
  230. #define ISW_OVERFLOW (1<<4) /* overflow */
  231. #define ISW_UNDERFLOW (1<<3) /* underflow */
  232. #define ISW_INEXACT (1<<2) /* inexact (precision) */
  233. #elif defined(_M_ALPHA)
  234. //
  235. // ICW is the Internal Control Word for transcendentals: all five exceptions
  236. // are masked and round to nearest mode is set. IMCW is the mask: all bits
  237. // are set, except for the ISW bits.
  238. //
  239. #define ICW (IEM_INEXACT | IEM_UNDERFLOW | IEM_OVERFLOW | IEM_ZERODIVIDE | IEM_INVALID | IRC_NEAR)
  240. #define ISW (ISW_INEXACT | ISW_UNDERFLOW | ISW_OVERFLOW | ISW_ZERODIVIDE | ISW_INVALID)
  241. #define IMCW (0xffffffff ^ ISW)
  242. //
  243. // The defines for the internal control word match the format of the Alpha
  244. // AXP software FPCR except for the rounding mode which is obtained from the
  245. // Alpha AXP hardware FPCR and shifted right 32 bits.
  246. //
  247. //
  248. // Internal Exception Mask bits.
  249. // Each bit _disables_ an exception (they are not _enable_ bits).
  250. //
  251. #define IMCW_EM 0x0000003e /* interrupt Exception Masks */
  252. #define IEM_INEXACT 0x00000020 /* inexact (precision) */
  253. #define IEM_UNDERFLOW 0x00000010 /* underflow */
  254. #define IEM_OVERFLOW 0x00000008 /* overflow */
  255. #define IEM_ZERODIVIDE 0x00000004 /* zero divide */
  256. #define IEM_INVALID 0x00000002 /* invalid */
  257. //
  258. // Internal Rounding Control values.
  259. //
  260. #define IMCW_RC (0x3 << 26) /* Rounding Control */
  261. #define IRC_CHOP (0x0 << 26) /* chop */
  262. #define IRC_DOWN (0x1 << 26) /* down */
  263. #define IRC_NEAR (0x2 << 26) /* near */
  264. #define IRC_UP (0x3 << 26) /* up */
  265. //
  266. // Internal Status Word bits.
  267. //
  268. #define ISW_INEXACT 0x00200000 /* inexact (precision) */
  269. #define ISW_UNDERFLOW 0x00100000 /* underflow */
  270. #define ISW_OVERFLOW 0x00080000 /* overflow */
  271. #define ISW_ZERODIVIDE 0x00040000 /* zero divide */
  272. #define ISW_INVALID 0x00020000 /* invalid */
  273. #elif defined(_M_PPC)
  274. #define IMCW_EM 0x000000f8 /* Exception Enable Mask */
  275. #define IEM_INVALID 0x00000080 /* invalid */
  276. #define IEM_OVERFLOW 0x00000040 /* overflow */
  277. #define IEM_UNDERFLOW 0x00000020 /* underflow */
  278. #define IEM_ZERODIVIDE 0x00000010 /* zero divide */
  279. #define IEM_INEXACT 0x00000008 /* inexact (precision) */
  280. #define IMCW_RC 0x00000003 /* Rounding Control Mask */
  281. #define IRC_NEAR 0x00000000 /* near */
  282. #define IRC_CHOP 0x00000001 /* chop */
  283. #define IRC_UP 0x00000002 /* up */
  284. #define IRC_DOWN 0x00000003 /* down */
  285. #define IMCW_SW 0x3E000000 /* Status Mask */
  286. #define ISW_INVALID 0x20000000 /* invalid summary */
  287. #define ISW_OVERFLOW 0x10000000 /* overflow */
  288. #define ISW_UNDERFLOW 0x08000000 /* underflow */
  289. #define ISW_ZERODIVIDE 0x04000000 /* zero divide */
  290. #define ISW_INEXACT 0x02000000 /* inexact (precision) */
  291. #define IMCW_VX 0x01F80700 /* Invalid Cause Mask */
  292. #define IVX_SNAN 0x01000000 /* SNaN */
  293. #define IVX_ISI 0x00800000 /* infinity - infinity */
  294. #define IVX_IDI 0x00400000 /* infinity / infinity */
  295. #define IVX_ZDZ 0x00200000 /* zero / zero */
  296. #define IVX_IMZ 0x00100000 /* infinity * zero */
  297. #define IVX_VC 0x00080000 /* inv flpt compare */
  298. #define IVX_SOFT 0x00000400 /* software request */
  299. #define IVX_SQRT 0x00000200 /* sqrt of negative */
  300. #define IVX_CVI 0x00000100 /* inv integer convert */
  301. /* Internal CW for transcendentals */
  302. #define ICW (IMCW_EM)
  303. /* Internal CW Mask (non-status bits) */
  304. #define IMCW (0xffffffff & (~(IMCW_SW|IMCW_VX)))
  305. #endif
  306. #ifndef __assembler /* MIPS ONLY: Protect from assembler */
  307. #define RETURN(fpcw,result) return _rstorfp(fpcw),(result)
  308. #define RETURN_INEXACT1(op,arg1,res,cw) \
  309. if (cw & IEM_INEXACT) { \
  310. _rstorfp(cw); \
  311. return res; \
  312. } \
  313. else { \
  314. return _except1(FP_P, op, arg1, res, cw); \
  315. }
  316. #define RETURN_INEXACT2(op,arg1,arg2,res,cw) \
  317. if (cw & IEM_INEXACT) { \
  318. _rstorfp(cw); \
  319. return res; \
  320. } \
  321. else { \
  322. return _except2(FP_P, op, arg1, arg2, res, cw); \
  323. }
  324. #ifdef _M_ALPHA
  325. //
  326. // Since fp32 is not compiled in IEEE exception mode perform Alpha NaN
  327. // propagation in software to avoid hardware/kernel trap involvement.
  328. //
  329. extern double _nan2qnan(double);
  330. #define _d_snan2(x,y) _nan2qnan(y)
  331. #define _s2qnan(x) _nan2qnan(x)
  332. #else
  333. //handle NaN propagation
  334. #define _d_snan2(x,y) ((x)+(y))
  335. #define _s2qnan(x) ((x)+1.0)
  336. #endif
  337. #define _maskfp() _ctrlfp(ICW, IMCW)
  338. #ifdef _M_ALPHA
  339. #define _rstorfp(cw) 0
  340. #else
  341. #define _rstorfp(cw) _ctrlfp(cw, IMCW)
  342. #endif
  343. #define ABS(x) ((x)<0 ? -(x) : (x) )
  344. int _d_inttype(double);
  345. #endif /* #ifndef __assembler */
  346. #define _D_NOINT 0
  347. #define _D_ODD 1
  348. #define _D_EVEN 2
  349. // IEEE exceptions
  350. #define FP_O 0x01
  351. #define FP_U 0x02
  352. #define FP_Z 0x04
  353. #define FP_I 0x08
  354. #define FP_P 0x10
  355. // An extra flag for matherr support
  356. // Set together with FP_I from trig functions when the argument is too large
  357. #define FP_TLOSS 0x20
  358. #ifndef __assembler /* MIPS ONLY: Protect from assembler */
  359. #ifdef B_END
  360. #define SET_DBL(msw, lsw) msw, lsw
  361. #else
  362. #define SET_DBL(msw, lsw) lsw, msw
  363. #endif
  364. #endif /* #ifndef __assembler */
  365. // special types
  366. #define T_PINF 1
  367. #define T_NINF 2
  368. #define T_QNAN 3
  369. #define T_SNAN 4
  370. // exponent adjustment for IEEE overflow/underflow exceptions
  371. // used before passing the result to the trap handler
  372. #define IEEE_ADJUST 1536
  373. // QNAN values
  374. #define INT_NAN (~0)
  375. #define QNAN_SQRT D_IND
  376. #define QNAN_LOG D_IND
  377. #define QNAN_LOG10 D_IND
  378. #define QNAN_POW D_IND
  379. #define QNAN_SINH D_IND
  380. #define QNAN_COSH D_IND
  381. #define QNAN_TANH D_IND
  382. #define QNAN_SIN1 D_IND
  383. #define QNAN_SIN2 D_IND
  384. #define QNAN_COS1 D_IND
  385. #define QNAN_COS2 D_IND
  386. #define QNAN_TAN1 D_IND
  387. #define QNAN_TAN2 D_IND
  388. #define QNAN_ACOS D_IND
  389. #define QNAN_ASIN D_IND
  390. #define QNAN_ATAN2 D_IND
  391. #define QNAN_CEIL D_IND
  392. #define QNAN_FLOOR D_IND
  393. #define QNAN_MODF D_IND
  394. #define QNAN_LDEXP D_IND
  395. #define QNAN_FMOD D_IND
  396. #define QNAN_FREXP D_IND
  397. /*
  398. * Function prototypes
  399. */
  400. #ifndef __assembler /* MIPS ONLY: Protect from assembler */
  401. double _set_exp(double x, int exp);
  402. double _set_bexp(double x, int exp);
  403. double _add_exp(double x, int exp);
  404. double _frnd(double);
  405. double _fsqrt(double);
  406. double _except1(int flags, int opcode, double arg, double res, uintptr_t cw);
  407. double _except2(int flags, int opcode, double arg1, double arg2, double res, uintptr_t cw);
  408. int _sptype(double);
  409. int _get_exp(double);
  410. double _decomp(double, int *);
  411. int _powhlp(double x, double y, double * result);
  412. extern unsigned int _fpstatus;
  413. double _frnd(double);
  414. double _exphlp(double, int *);
  415. double _handle_qnan1(unsigned int op, double arg, uintptr_t cw);
  416. double _handle_qnan2(unsigned int op,double arg1,double arg2,uintptr_t cw);
  417. unsigned int _clhwfp(void);
  418. unsigned int _setfpcw(uintptr_t);
  419. int _errcode(unsigned int flags);
  420. void _set_errno(int matherrtype);
  421. int _handle_exc(unsigned int flags, double * presult, uintptr_t cw);
  422. uintptr_t _clrfp(void);
  423. uintptr_t _ctrlfp(uintptr_t,uintptr_t);
  424. uintptr_t _statfp(void);
  425. void _set_statfp(uintptr_t);
  426. #endif /* #ifndef __assembler */
  427. #ifdef __cplusplus
  428. }
  429. #endif
  430. #define _INC_TRANS
  431. #endif /* _INC_TRANS */