ieee754_float128.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* _Float128 IEEE like macros.
  2. Copyright (C) 2017-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #ifndef _IEEE754_FLOAT128_H
  16. #define _IEEE754_FLOAT128_H
  17. #include <endian.h>
  18. #include <stdint.h>
  19. # if __FLOAT_WORD_ORDER == BIG_ENDIAN
  20. # define __FLT_EORDER2(t, a, b) t a; t b;
  21. # define __FLT_EORDER4(t, a, b, c, d) \
  22. t a; t b; t c; t d;
  23. # define __FLT_EORDER6(t, a, b, c, d, e, f) \
  24. t a; t b; t c; t d; t e; t f;
  25. # define __FLT_EORDER7(t, a, b, c, d, e, f, g) \
  26. t a; t b; t c; t d; t e; t f; t g;
  27. # else
  28. # define __FLT_EORDER2(t, a, b) \
  29. t b; t a;
  30. # define __FLT_EORDER4(t, a, b, c, d) \
  31. t d; t c; t b; t a;
  32. # define __FLT_EORDER6(t, a, b, c, d, e, f) \
  33. t f; t e; t d; t c; t b; t a;
  34. # define __FLT_EORDER7(t, a, b, c, d, e, f, g) \
  35. t g; t f; t e; t d; t c; t b; t a;
  36. # endif
  37. /* A union which permits us to convert between _Float128 and
  38. four 32 bit ints or two 64 bit ints. */
  39. typedef union
  40. {
  41. _Float128 value;
  42. struct
  43. {
  44. __FLT_EORDER2 (uint64_t, msw, lsw);
  45. } parts64;
  46. struct
  47. {
  48. __FLT_EORDER4 (uint32_t, w0, w1, w2, w3);
  49. } parts32;
  50. } ieee854_float128_shape_type;
  51. /* Get two 64 bit ints from a _Float128. */
  52. # define GET_FLOAT128_WORDS64(ix0,ix1,d) \
  53. do { \
  54. ieee854_float128_shape_type qw_u; \
  55. qw_u.value = (d); \
  56. (ix0) = qw_u.parts64.msw; \
  57. (ix1) = qw_u.parts64.lsw; \
  58. } while (0)
  59. /* Set a _Float128 from two 64 bit ints. */
  60. # define SET_FLOAT128_WORDS64(d,ix0,ix1) \
  61. do { \
  62. ieee854_float128_shape_type qw_u; \
  63. qw_u.parts64.msw = (ix0); \
  64. qw_u.parts64.lsw = (ix1); \
  65. (d) = qw_u.value; \
  66. } while (0)
  67. /* Get the more significant 64 bits of a _Float128 mantissa. */
  68. # define GET_FLOAT128_MSW64(v,d) \
  69. do { \
  70. ieee854_float128_shape_type sh_u; \
  71. sh_u.value = (d); \
  72. (v) = sh_u.parts64.msw; \
  73. } while (0)
  74. /* Set the more significant 64 bits of a _Float128 mantissa from an int. */
  75. # define SET_FLOAT128_MSW64(d,v) \
  76. do { \
  77. ieee854_float128_shape_type sh_u; \
  78. sh_u.value = (d); \
  79. sh_u.parts64.msw = (v); \
  80. (d) = sh_u.value; \
  81. } while (0)
  82. /* Get the least significant 64 bits of a _Float128 mantissa. */
  83. # define GET_FLOAT128_LSW64(v,d) \
  84. do { \
  85. ieee854_float128_shape_type sh_u; \
  86. sh_u.value = (d); \
  87. (v) = sh_u.parts64.lsw; \
  88. } while (0)
  89. /* Likewise, some helper macros which are exposed via ieee754.h for
  90. C99 real types, but not _Float128. */
  91. union ieee854_float128
  92. {
  93. _Float128 d;
  94. /* This is the IEEE 854 quad-precision format. */
  95. struct
  96. {
  97. __FLT_EORDER6 (unsigned int, negative:1,
  98. exponent:15,
  99. mantissa0:16,
  100. mantissa1:32,
  101. mantissa2:32,
  102. mantissa3:32)
  103. } ieee;
  104. /* This format makes it easier to see if a NaN is a signalling NaN. */
  105. struct
  106. {
  107. __FLT_EORDER7 (unsigned int, negative:1,
  108. exponent:15,
  109. quiet_nan:1,
  110. mantissa0:15,
  111. mantissa1:32,
  112. mantissa2:32,
  113. mantissa3:32)
  114. } ieee_nan;
  115. };
  116. #define IEEE854_FLOAT128_BIAS 0x3fff /* Added to exponent. */
  117. #endif