math_private.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. */
  14. #ifndef _MATH_PRIVATE_H_
  15. #define _MATH_PRIVATE_H_
  16. #include <endian.h>
  17. #include <stdbool.h>
  18. #include <stdint.h>
  19. #include <sys/types.h>
  20. /* Gather machine dependent _Floatn support. */
  21. #include <bits/floatn.h>
  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. /* A union which permits us to convert between a double and two 32 bit
  33. ints. */
  34. #if __FLOAT_WORD_ORDER == __BIG_ENDIAN
  35. typedef union
  36. {
  37. double value;
  38. struct
  39. {
  40. uint32_t msw;
  41. uint32_t lsw;
  42. } parts;
  43. uint64_t word;
  44. } ieee_double_shape_type;
  45. #endif
  46. #if __FLOAT_WORD_ORDER == __LITTLE_ENDIAN
  47. typedef union
  48. {
  49. double value;
  50. struct
  51. {
  52. uint32_t lsw;
  53. uint32_t msw;
  54. } parts;
  55. uint64_t word;
  56. } ieee_double_shape_type;
  57. #endif
  58. /* Get two 32 bit ints from a double. */
  59. #define EXTRACT_WORDS(ix0,ix1,d) \
  60. do { \
  61. ieee_double_shape_type ew_u; \
  62. ew_u.value = (d); \
  63. (ix0) = ew_u.parts.msw; \
  64. (ix1) = ew_u.parts.lsw; \
  65. } while (0)
  66. /* Get the more significant 32 bit int from a double. */
  67. #ifndef GET_HIGH_WORD
  68. # define GET_HIGH_WORD(i,d) \
  69. do { \
  70. ieee_double_shape_type gh_u; \
  71. gh_u.value = (d); \
  72. (i) = gh_u.parts.msw; \
  73. } while (0)
  74. #endif
  75. /* Get the less significant 32 bit int from a double. */
  76. #ifndef GET_LOW_WORD
  77. # define GET_LOW_WORD(i,d) \
  78. do { \
  79. ieee_double_shape_type gl_u; \
  80. gl_u.value = (d); \
  81. (i) = gl_u.parts.lsw; \
  82. } while (0)
  83. #endif
  84. /* Get all in one, efficient on 64-bit machines. */
  85. #ifndef EXTRACT_WORDS64
  86. # define EXTRACT_WORDS64(i,d) \
  87. do { \
  88. ieee_double_shape_type gh_u; \
  89. gh_u.value = (d); \
  90. (i) = gh_u.word; \
  91. } while (0)
  92. #endif
  93. /* Set a double from two 32 bit ints. */
  94. #ifndef INSERT_WORDS
  95. # define INSERT_WORDS(d,ix0,ix1) \
  96. do { \
  97. ieee_double_shape_type iw_u; \
  98. iw_u.parts.msw = (ix0); \
  99. iw_u.parts.lsw = (ix1); \
  100. (d) = iw_u.value; \
  101. } while (0)
  102. #endif
  103. /* Get all in one, efficient on 64-bit machines. */
  104. #ifndef INSERT_WORDS64
  105. # define INSERT_WORDS64(d,i) \
  106. do { \
  107. ieee_double_shape_type iw_u; \
  108. iw_u.word = (i); \
  109. (d) = iw_u.value; \
  110. } while (0)
  111. #endif
  112. /* Set the more significant 32 bits of a double from an int. */
  113. #ifndef SET_HIGH_WORD
  114. #define SET_HIGH_WORD(d,v) \
  115. do { \
  116. ieee_double_shape_type sh_u; \
  117. sh_u.value = (d); \
  118. sh_u.parts.msw = (v); \
  119. (d) = sh_u.value; \
  120. } while (0)
  121. #endif
  122. /* Set the less significant 32 bits of a double from an int. */
  123. #ifndef SET_LOW_WORD
  124. # define SET_LOW_WORD(d,v) \
  125. do { \
  126. ieee_double_shape_type sl_u; \
  127. sl_u.value = (d); \
  128. sl_u.parts.lsw = (v); \
  129. (d) = sl_u.value; \
  130. } while (0)
  131. #endif
  132. /* A union which permits us to convert between a float and a 32 bit
  133. int. */
  134. typedef union
  135. {
  136. float value;
  137. uint32_t word;
  138. } ieee_float_shape_type;
  139. /* Get a 32 bit int from a float. */
  140. #ifndef GET_FLOAT_WORD
  141. # define GET_FLOAT_WORD(i,d) \
  142. do { \
  143. ieee_float_shape_type gf_u; \
  144. gf_u.value = (d); \
  145. (i) = gf_u.word; \
  146. } while (0)
  147. #endif
  148. /* Set a float from a 32 bit int. */
  149. #ifndef SET_FLOAT_WORD
  150. # define SET_FLOAT_WORD(d,i) \
  151. do { \
  152. ieee_float_shape_type sf_u; \
  153. sf_u.word = (i); \
  154. (d) = sf_u.value; \
  155. } while (0)
  156. #endif
  157. /* We need to guarantee an expansion of name when building
  158. ldbl-128 files as another type (e.g _Float128). */
  159. #define mathx_hidden_def(name) hidden_def(name)
  160. /* Get long double macros from a separate header. */
  161. #include <math_ldbl.h>
  162. /* Include function declarations for each floating-point. */
  163. #define _Mdouble_ double
  164. #define _MSUF_
  165. #include <math_private_calls.h>
  166. #undef _MSUF_
  167. #undef _Mdouble_
  168. #define _Mdouble_ float
  169. #define _MSUF_ f
  170. #define __MATH_DECLARING_FLOAT
  171. #include <math_private_calls.h>
  172. #undef __MATH_DECLARING_FLOAT
  173. #undef _MSUF_
  174. #undef _Mdouble_
  175. #define _Mdouble_ long double
  176. #define _MSUF_ l
  177. #define __MATH_DECLARING_LONG_DOUBLE
  178. #include <math_private_calls.h>
  179. #undef __MATH_DECLARING_LONG_DOUBLE
  180. #undef _MSUF_
  181. #undef _Mdouble_
  182. #if __HAVE_DISTINCT_FLOAT128
  183. # define _Mdouble_ _Float128
  184. # define _MSUF_ f128
  185. # define __MATH_DECLARING_FLOATN
  186. # include <math_private_calls.h>
  187. # undef __MATH_DECLARING_FLOATN
  188. # undef _MSUF_
  189. # undef _Mdouble_
  190. #endif
  191. /* Prototypes for functions of the IBM Accurate Mathematical Library. */
  192. extern double __sin (double __x);
  193. extern double __cos (double __x);
  194. extern int __branred (double __x, double *__a, double *__aa);
  195. extern void __doasin (double __x, double __dx, double __v[]);
  196. extern void __dubsin (double __x, double __dx, double __v[]);
  197. extern void __dubcos (double __x, double __dx, double __v[]);
  198. extern double __sin32 (double __x, double __res, double __res1);
  199. extern double __cos32 (double __x, double __res, double __res1);
  200. extern double __mpsin (double __x, double __dx, bool __range_reduce);
  201. extern double __mpcos (double __x, double __dx, bool __range_reduce);
  202. extern void __docos (double __x, double __dx, double __v[]);
  203. #endif /* _MATH_PRIVATE_H_ */