quadmath-imp.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* GCC Quad-Precision Math Library
  2. Copyright (C) 2010, 2011 Free Software Foundation, Inc.
  3. Written by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
  4. This file is part of the libquadmath library.
  5. Libquadmath is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9. Libquadmath is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with libquadmath; see the file COPYING.LIB. If
  15. not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
  16. Boston, MA 02110-1301, USA. */
  17. #ifndef QUADMATH_IMP_H
  18. #define QUADMATH_IMP_H
  19. #include <stdint.h>
  20. #include <stdlib.h>
  21. #include "quadmath.h"
  22. #include "config.h"
  23. /* Under IEEE 754, an architecture may determine tininess of
  24. floating-point results either "before rounding" or "after
  25. rounding", but must do so in the same way for all operations
  26. returning binary results. Define TININESS_AFTER_ROUNDING to 1 for
  27. "after rounding" architectures, 0 for "before rounding"
  28. architectures. */
  29. #define TININESS_AFTER_ROUNDING 1
  30. /* Prototypes for internal functions. */
  31. extern int32_t __quadmath_rem_pio2q (__float128, __float128 *);
  32. extern void __quadmath_kernel_sincosq (__float128, __float128, __float128 *,
  33. __float128 *, int);
  34. extern __float128 __quadmath_kernel_sinq (__float128, __float128, int);
  35. extern __float128 __quadmath_kernel_cosq (__float128, __float128);
  36. extern __float128 __quadmath_x2y2m1q (__float128 x, __float128 y);
  37. extern int __quadmath_isinf_nsq (__float128 x);
  38. /* Frankly, if you have __float128, you have 64-bit integers, right? */
  39. #ifndef UINT64_C
  40. # error "No way!"
  41. #endif
  42. /* Main union type we use to manipulate the floating-point type. */
  43. typedef union
  44. {
  45. __float128 value;
  46. struct
  47. #ifdef __MINGW32__
  48. /* On mingw targets the ms-bitfields option is active by default.
  49. Therefore enforce gnu-bitfield style. */
  50. __attribute__ ((gcc_struct))
  51. #endif
  52. {
  53. #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  54. unsigned negative:1;
  55. unsigned exponent:15;
  56. uint64_t mant_high:48;
  57. uint64_t mant_low:64;
  58. #else
  59. uint64_t mant_low:64;
  60. uint64_t mant_high:48;
  61. unsigned exponent:15;
  62. unsigned negative:1;
  63. #endif
  64. } ieee;
  65. struct
  66. {
  67. #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  68. uint64_t high;
  69. uint64_t low;
  70. #else
  71. uint64_t low;
  72. uint64_t high;
  73. #endif
  74. } words64;
  75. struct
  76. {
  77. #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  78. uint32_t w0;
  79. uint32_t w1;
  80. uint32_t w2;
  81. uint32_t w3;
  82. #else
  83. uint32_t w3;
  84. uint32_t w2;
  85. uint32_t w1;
  86. uint32_t w0;
  87. #endif
  88. } words32;
  89. struct
  90. #ifdef __MINGW32__
  91. /* Make sure we are using gnu-style bitfield handling. */
  92. __attribute__ ((gcc_struct))
  93. #endif
  94. {
  95. #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  96. unsigned negative:1;
  97. unsigned exponent:15;
  98. unsigned quiet_nan:1;
  99. uint64_t mant_high:47;
  100. uint64_t mant_low:64;
  101. #else
  102. uint64_t mant_low:64;
  103. uint64_t mant_high:47;
  104. unsigned quiet_nan:1;
  105. unsigned exponent:15;
  106. unsigned negative:1;
  107. #endif
  108. } nan;
  109. } ieee854_float128;
  110. /* Get two 64 bit ints from a long double. */
  111. #define GET_FLT128_WORDS64(ix0,ix1,d) \
  112. do { \
  113. ieee854_float128 u; \
  114. u.value = (d); \
  115. (ix0) = u.words64.high; \
  116. (ix1) = u.words64.low; \
  117. } while (0)
  118. /* Set a long double from two 64 bit ints. */
  119. #define SET_FLT128_WORDS64(d,ix0,ix1) \
  120. do { \
  121. ieee854_float128 u; \
  122. u.words64.high = (ix0); \
  123. u.words64.low = (ix1); \
  124. (d) = u.value; \
  125. } while (0)
  126. /* Get the more significant 64 bits of a long double mantissa. */
  127. #define GET_FLT128_MSW64(v,d) \
  128. do { \
  129. ieee854_float128 u; \
  130. u.value = (d); \
  131. (v) = u.words64.high; \
  132. } while (0)
  133. /* Set the more significant 64 bits of a long double mantissa from an int. */
  134. #define SET_FLT128_MSW64(d,v) \
  135. do { \
  136. ieee854_float128 u; \
  137. u.value = (d); \
  138. u.words64.high = (v); \
  139. (d) = u.value; \
  140. } while (0)
  141. /* Get the least significant 64 bits of a long double mantissa. */
  142. #define GET_FLT128_LSW64(v,d) \
  143. do { \
  144. ieee854_float128 u; \
  145. u.value = (d); \
  146. (v) = u.words64.low; \
  147. } while (0)
  148. #define IEEE854_FLOAT128_BIAS 0x3fff
  149. #define QUADFP_NAN 0
  150. #define QUADFP_INFINITE 1
  151. #define QUADFP_ZERO 2
  152. #define QUADFP_SUBNORMAL 3
  153. #define QUADFP_NORMAL 4
  154. #define fpclassifyq(x) \
  155. __builtin_fpclassify (QUADFP_NAN, QUADFP_INFINITE, QUADFP_NORMAL, \
  156. QUADFP_SUBNORMAL, QUADFP_ZERO, x)
  157. #endif