math_private.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /*
  2. * ====================================================
  3. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  4. *
  5. * Developed at SunPro, a Sun Microsystems, Inc. business.
  6. * Permission to use, copy, modify, and distribute this
  7. * software is freely granted, provided that this notice
  8. * is preserved.
  9. * ====================================================
  10. */
  11. /*
  12. * from: @(#)fdlibm.h 5.1 93/09/24
  13. * $FreeBSD: src/lib/msun/src/math_private.h,v 1.34 2011/10/21 06:27:56 das Exp $
  14. */
  15. #ifndef _MATH_PRIVATE_H_
  16. #define _MATH_PRIVATE_H_
  17. #include "types-compat.h"
  18. #include "fpmath.h"
  19. #include <complex.h>
  20. #include <stdint.h>
  21. /*
  22. * The original fdlibm code used statements like:
  23. * n0 = ((*(int*)&one)>>29)^1; * index of high word *
  24. * ix0 = *(n0+(int*)&x); * high word of x *
  25. * ix1 = *((1-n0)+(int*)&x); * low word of x *
  26. * to dig two 32 bit words out of the 64 bit IEEE floating point
  27. * value. That is non-ANSI, and, moreover, the gcc instruction
  28. * scheduler gets it wrong. We instead use the following macros.
  29. * Unlike the original code, we determine the endianness at compile
  30. * time, not at run time; I don't see much benefit to selecting
  31. * endianness at run time.
  32. */
  33. /*
  34. * A union which permits us to convert between a double and two 32 bit
  35. * ints.
  36. */
  37. #if _IEEE_WORD_ORDER == _BIG_ENDIAN
  38. typedef union
  39. {
  40. double value;
  41. struct
  42. {
  43. u_int32_t msw;
  44. u_int32_t lsw;
  45. } parts;
  46. struct
  47. {
  48. u_int64_t w;
  49. } xparts;
  50. } ieee_double_shape_type;
  51. #endif
  52. #if _IEEE_WORD_ORDER == _LITTLE_ENDIAN
  53. typedef union
  54. {
  55. double value;
  56. struct
  57. {
  58. u_int32_t lsw;
  59. u_int32_t msw;
  60. } parts;
  61. struct
  62. {
  63. u_int64_t w;
  64. } xparts;
  65. } ieee_double_shape_type;
  66. #endif
  67. /* Get two 32 bit ints from a double. */
  68. #define EXTRACT_WORDS(ix0,ix1,d) \
  69. do { \
  70. ieee_double_shape_type ew_u; \
  71. ew_u.value = (d); \
  72. (ix0) = ew_u.parts.msw; \
  73. (ix1) = ew_u.parts.lsw; \
  74. } while (0)
  75. /* Get a 64-bit int from a double. */
  76. #define EXTRACT_WORD64(ix,d) \
  77. do { \
  78. ieee_double_shape_type ew_u; \
  79. ew_u.value = (d); \
  80. (ix) = ew_u.xparts.w; \
  81. } while (0)
  82. /* Get the more significant 32 bit int from a double. */
  83. #define GET_HIGH_WORD(i,d) \
  84. do { \
  85. ieee_double_shape_type gh_u; \
  86. gh_u.value = (d); \
  87. (i) = gh_u.parts.msw; \
  88. } while (0)
  89. /* Get the less significant 32 bit int from a double. */
  90. #define GET_LOW_WORD(i,d) \
  91. do { \
  92. ieee_double_shape_type gl_u; \
  93. gl_u.value = (d); \
  94. (i) = gl_u.parts.lsw; \
  95. } while (0)
  96. /* Set a double from two 32 bit ints. */
  97. #define INSERT_WORDS(d,ix0,ix1) \
  98. do { \
  99. ieee_double_shape_type iw_u; \
  100. iw_u.parts.msw = (ix0); \
  101. iw_u.parts.lsw = (ix1); \
  102. (d) = iw_u.value; \
  103. } while (0)
  104. /* Set a double from a 64-bit int. */
  105. #define INSERT_WORD64(d,ix) \
  106. do { \
  107. ieee_double_shape_type iw_u; \
  108. iw_u.xparts.w = (ix); \
  109. (d) = iw_u.value; \
  110. } while (0)
  111. /* Set the more significant 32 bits of a double from an int. */
  112. #define SET_HIGH_WORD(d,v) \
  113. do { \
  114. ieee_double_shape_type sh_u; \
  115. sh_u.value = (d); \
  116. sh_u.parts.msw = (v); \
  117. (d) = sh_u.value; \
  118. } while (0)
  119. /* Set the less significant 32 bits of a double from an int. */
  120. #define SET_LOW_WORD(d,v) \
  121. do { \
  122. ieee_double_shape_type sl_u; \
  123. sl_u.value = (d); \
  124. sl_u.parts.lsw = (v); \
  125. (d) = sl_u.value; \
  126. } while (0)
  127. /*
  128. * A union which permits us to convert between a float and a 32 bit
  129. * int.
  130. */
  131. typedef union
  132. {
  133. float value;
  134. /* FIXME: Assumes 32 bit int. */
  135. unsigned int word;
  136. } ieee_float_shape_type;
  137. /* Get a 32 bit int from a float. */
  138. #define GET_FLOAT_WORD(i,d) \
  139. do { \
  140. ieee_float_shape_type gf_u; \
  141. gf_u.value = (d); \
  142. (i) = gf_u.word; \
  143. } while (0)
  144. /* Set a float from a 32 bit int. */
  145. #define SET_FLOAT_WORD(d,i) \
  146. do { \
  147. ieee_float_shape_type sf_u; \
  148. sf_u.word = (i); \
  149. (d) = sf_u.value; \
  150. } while (0)
  151. /* Get expsign as a 16 bit int from a long double. */
  152. #define GET_LDBL_EXPSIGN(i,d) \
  153. do { \
  154. union IEEEl2bits ge_u; \
  155. ge_u.e = (d); \
  156. (i) = ge_u.xbits.expsign; \
  157. } while (0)
  158. /* Set expsign of a long double from a 16 bit int. */
  159. #define SET_LDBL_EXPSIGN(d,v) \
  160. do { \
  161. union IEEEl2bits se_u; \
  162. se_u.e = (d); \
  163. se_u.xbits.expsign = (v); \
  164. (d) = se_u.e; \
  165. } while (0)
  166. //VBS
  167. #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
  168. /* VBS
  169. #ifdef FLT_EVAL_METHOD
  170. // Attempt to get strict C99 semantics for assignment with non-C99 compilers.
  171. #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
  172. #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
  173. #else
  174. #define STRICT_ASSIGN(type, lval, rval) do { \
  175. volatile type __lval; \
  176. \
  177. if (sizeof(type) >= sizeof(double)) \
  178. (lval) = (rval); \
  179. else { \
  180. __lval = (rval); \
  181. (lval) = __lval; \
  182. } \
  183. } while (0)
  184. #endif
  185. #endif
  186. */
  187. /*
  188. * Common routine to process the arguments to nan(), nanf(), and nanl().
  189. */
  190. void _scan_nan(u_int32_t *__words, int __num_words, const char *__s);
  191. //VBS
  192. //#ifdef _COMPLEX_H
  193. /*
  194. * C99 specifies that complex numbers have the same representation as
  195. * an array of two elements, where the first element is the real part
  196. * and the second element is the imaginary part.
  197. */
  198. typedef union {
  199. float complex f;
  200. float a[2];
  201. } float_complex;
  202. typedef union {
  203. double complex f;
  204. double a[2];
  205. } double_complex;
  206. typedef union {
  207. long double complex f;
  208. long double a[2];
  209. } long_double_complex;
  210. #define REALPART(z) ((z).a[0])
  211. #define IMAGPART(z) ((z).a[1])
  212. /*
  213. * Inline functions that can be used to construct complex values.
  214. *
  215. * The C99 standard intends x+I*y to be used for this, but x+I*y is
  216. * currently unusable in general since gcc introduces many overflow,
  217. * underflow, sign and efficiency bugs by rewriting I*y as
  218. * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product.
  219. * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted
  220. * to -0.0+I*0.0.
  221. *
  222. * In C11, a CMPLX(x,y) macro was added to circumvent this limitation,
  223. * and gcc 4.7 added a __builtin_complex feature to simplify implementation
  224. * of CMPLX in libc, so we can take advantage of these features if they
  225. * are available.
  226. */
  227. #if defined(CMPLXF) && defined(CMPLX) && defined(CMPLXL) /* C11 */
  228. # define cpackf(x,y) CMPLXF(x,y)
  229. # define cpack(x,y) CMPLX(x,y)
  230. # define cpackl(x,y) CMPLXL(x,y)
  231. #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER)
  232. # define cpackf(x,y) __builtin_complex ((float) (x), (float) (y))
  233. # define cpack(x,y) __builtin_complex ((double) (x), (double) (y))
  234. # define cpackl(x,y) __builtin_complex ((long double) (x), (long double) (y))
  235. #else /* define our own cpack functions */
  236. static __inline float complex
  237. cpackf(float x, float y)
  238. {
  239. float_complex z;
  240. REALPART(z) = x;
  241. IMAGPART(z) = y;
  242. return (z.f);
  243. }
  244. static __inline double complex
  245. cpack(double x, double y)
  246. {
  247. double_complex z;
  248. REALPART(z) = x;
  249. IMAGPART(z) = y;
  250. return (z.f);
  251. }
  252. static __inline long double complex
  253. cpackl(long double x, long double y)
  254. {
  255. long_double_complex z;
  256. REALPART(z) = x;
  257. IMAGPART(z) = y;
  258. return (z.f);
  259. }
  260. #endif /* define our own cpack functions */
  261. //VBS
  262. //#endif /* _COMPLEX_H */
  263. #ifdef __GNUCLIKE_ASM
  264. /* Asm versions of some functions. */
  265. #ifdef __amd64__
  266. static __inline int
  267. irint(double x)
  268. {
  269. int n;
  270. __asm__("cvtsd2si %1,%0" : "=r" (n) : "x" (x));
  271. return (n);
  272. }
  273. #define HAVE_EFFICIENT_IRINT
  274. #endif
  275. #ifdef __i386__
  276. static __inline int
  277. irint(double x)
  278. {
  279. int n;
  280. __asm__("fistl %0" : "=m" (n) : "t" (x));
  281. return (n);
  282. }
  283. #define HAVE_EFFICIENT_IRINT
  284. #endif
  285. #endif /* __GNUCLIKE_ASM */
  286. /*
  287. * ieee style elementary functions
  288. *
  289. * We rename functions here to improve other sources' diffability
  290. * against fdlibm.
  291. */
  292. #define __ieee754_sqrt sqrt
  293. #define __ieee754_acos acos
  294. #define __ieee754_acosh acosh
  295. #define __ieee754_log log
  296. #define __ieee754_log2 log2
  297. #define __ieee754_atanh atanh
  298. #define __ieee754_asin asin
  299. #define __ieee754_atan2 atan2
  300. #define __ieee754_exp exp
  301. #define __ieee754_cosh cosh
  302. #define __ieee754_fmod fmod
  303. #define __ieee754_pow pow
  304. #define __ieee754_lgamma lgamma
  305. #define __ieee754_gamma gamma
  306. #define __ieee754_lgamma_r lgamma_r
  307. #define __ieee754_gamma_r gamma_r
  308. #define __ieee754_log10 log10
  309. #define __ieee754_sinh sinh
  310. #define __ieee754_hypot hypot
  311. #define __ieee754_j0 j0
  312. #define __ieee754_j1 j1
  313. #define __ieee754_y0 y0
  314. #define __ieee754_y1 y1
  315. #define __ieee754_jn jn
  316. #define __ieee754_yn yn
  317. #define __ieee754_remainder remainder
  318. #define __ieee754_scalb scalb
  319. #define __ieee754_sqrtf sqrtf
  320. #define __ieee754_acosf acosf
  321. #define __ieee754_acoshf acoshf
  322. #define __ieee754_logf logf
  323. #define __ieee754_atanhf atanhf
  324. #define __ieee754_asinf asinf
  325. #define __ieee754_atan2f atan2f
  326. #define __ieee754_expf expf
  327. #define __ieee754_coshf coshf
  328. #define __ieee754_fmodf fmodf
  329. #define __ieee754_powf powf
  330. #define __ieee754_lgammaf lgammaf
  331. #define __ieee754_gammaf gammaf
  332. #define __ieee754_lgammaf_r lgammaf_r
  333. #define __ieee754_gammaf_r gammaf_r
  334. #define __ieee754_log10f log10f
  335. #define __ieee754_log2f log2f
  336. #define __ieee754_sinhf sinhf
  337. #define __ieee754_hypotf hypotf
  338. #define __ieee754_j0f j0f
  339. #define __ieee754_j1f j1f
  340. #define __ieee754_y0f y0f
  341. #define __ieee754_y1f y1f
  342. #define __ieee754_jnf jnf
  343. #define __ieee754_ynf ynf
  344. #define __ieee754_remainderf remainderf
  345. #define __ieee754_scalbf scalbf
  346. /* fdlibm kernel function */
  347. int __kernel_rem_pio2(double*,double*,int,int,int);
  348. /* double precision kernel functions */
  349. #ifdef INLINE_REM_PIO2
  350. __inline
  351. #endif
  352. int __ieee754_rem_pio2(double,double*);
  353. double __kernel_sin(double,double,int);
  354. double __kernel_cos(double,double);
  355. double __kernel_tan(double,double,int);
  356. double __ldexp_exp(double,int);
  357. #ifdef _COMPLEX_H
  358. double complex __ldexp_cexp(double complex,int);
  359. #endif
  360. /* float precision kernel functions */
  361. #ifdef INLINE_REM_PIO2F
  362. __inline
  363. #endif
  364. int __ieee754_rem_pio2f(float,double*);
  365. #ifdef INLINE_KERNEL_SINDF
  366. __inline
  367. #endif
  368. float __kernel_sindf(double);
  369. #ifdef INLINE_KERNEL_COSDF
  370. __inline
  371. #endif
  372. float __kernel_cosdf(double);
  373. #ifdef INLINE_KERNEL_TANDF
  374. __inline
  375. #endif
  376. float __kernel_tandf(double,int);
  377. float __ldexp_expf(float,int);
  378. #ifdef _COMPLEX_H
  379. float complex __ldexp_cexpf(float complex,int);
  380. #endif
  381. /* long double precision kernel functions */
  382. long double __kernel_sinl(long double, long double, int);
  383. long double __kernel_cosl(long double, long double);
  384. long double __kernel_tanl(long double, long double, int);
  385. #endif /* !_MATH_PRIVATE_H_ */