1 | #ifndef _MATH_H |
---|---|

2 | |

3 | #ifdef _ISOMAC |

4 | # undef NO_LONG_DOUBLE |

5 | #endif |

6 | |

7 | #include <math/math.h> |

8 | |

9 | #ifndef _ISOMAC |

10 | /* Now define the internal interfaces. */ |

11 | extern int __signgam; |

12 | |

13 | # if IS_IN (libc) || IS_IN (libm) |

14 | hidden_proto (__finite) |

15 | hidden_proto (__isinf) |

16 | hidden_proto (__isnan) |

17 | hidden_proto (__finitef) |

18 | hidden_proto (__isinff) |

19 | hidden_proto (__isnanf) |

20 | |

21 | # if !defined __NO_LONG_DOUBLE_MATH \ |

22 | && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0 |

23 | hidden_proto (__finitel) |

24 | hidden_proto (__isinfl) |

25 | hidden_proto (__isnanl) |

26 | # endif |

27 | |

28 | # if __HAVE_DISTINCT_FLOAT128 |

29 | hidden_proto (__finitef128) |

30 | hidden_proto (__isinff128) |

31 | hidden_proto (__isnanf128) |

32 | # endif |

33 | # endif |

34 | |

35 | libm_hidden_proto (__fpclassify) |

36 | libm_hidden_proto (__fpclassifyf) |

37 | libm_hidden_proto (__issignaling) |

38 | libm_hidden_proto (__issignalingf) |

39 | libm_hidden_proto (__exp) |

40 | libm_hidden_proto (__expf) |

41 | |

42 | # if !defined __NO_LONG_DOUBLE_MATH \ |

43 | && __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0 |

44 | libm_hidden_proto (__fpclassifyl) |

45 | libm_hidden_proto (__issignalingl) |

46 | libm_hidden_proto (__expl) |

47 | libm_hidden_proto (__expm1l) |

48 | # endif |

49 | |

50 | # if __HAVE_DISTINCT_FLOAT128 |

51 | libm_hidden_proto (__fpclassifyf128) |

52 | libm_hidden_proto (__issignalingf128) |

53 | libm_hidden_proto (__expf128) |

54 | libm_hidden_proto (__expm1f128) |

55 | # endif |

56 | |

57 | #include <stdint.h> |

58 | #include <nan-high-order-bit.h> |

59 | |

60 | /* A union which permits us to convert between a float and a 32 bit |

61 | int. */ |

62 | |

63 | typedef union |

64 | { |

65 | float value; |

66 | uint32_t word; |

67 | } ieee_float_shape_type; |

68 | |

69 | /* Get a 32 bit int from a float. */ |

70 | #ifndef GET_FLOAT_WORD |

71 | # define GET_FLOAT_WORD(i,d) \ |

72 | do { \ |

73 | ieee_float_shape_type gf_u; \ |

74 | gf_u.value = (d); \ |

75 | (i) = gf_u.word; \ |

76 | } while (0) |

77 | #endif |

78 | |

79 | /* Set a float from a 32 bit int. */ |

80 | #ifndef SET_FLOAT_WORD |

81 | # define SET_FLOAT_WORD(d,i) \ |

82 | do { \ |

83 | ieee_float_shape_type sf_u; \ |

84 | sf_u.word = (i); \ |

85 | (d) = sf_u.value; \ |

86 | } while (0) |

87 | #endif |

88 | |

89 | extern inline int |

90 | __issignalingf (float x) |

91 | { |

92 | uint32_t xi; |

93 | GET_FLOAT_WORD (xi, x); |

94 | #if HIGH_ORDER_BIT_IS_SET_FOR_SNAN |

95 | /* We only have to care about the high-order bit of x's significand, because |

96 | having it set (sNaN) already makes the significand different from that |

97 | used to designate infinity. */ |

98 | return (xi & 0x7fc00000) == 0x7fc00000; |

99 | #else |

100 | /* To keep the following comparison simple, toggle the quiet/signaling bit, |

101 | so that it is set for sNaNs. This is inverse to IEEE 754-2008 (as well as |

102 | common practice for IEEE 754-1985). */ |

103 | xi ^= 0x00400000; |

104 | /* We have to compare for greater (instead of greater or equal), because x's |

105 | significand being all-zero designates infinity not NaN. */ |

106 | return (xi & 0x7fffffff) > 0x7fc00000; |

107 | #endif |

108 | } |

109 | |

110 | # if __HAVE_DISTINCT_FLOAT128 |

111 | |

112 | /* __builtin_isinf_sign is broken in GCC < 7 for float128. */ |

113 | # if ! __GNUC_PREREQ (7, 0) |

114 | # include <ieee754_float128.h> |

115 | extern inline int |

116 | __isinff128 (_Float128 x) |

117 | { |

118 | int64_t hx, lx; |

119 | GET_FLOAT128_WORDS64 (hx, lx, x); |

120 | lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7fff000000000000LL; |

121 | lx |= -lx; |

122 | return ~(lx >> 63) & (hx >> 62); |

123 | } |

124 | # endif |

125 | |

126 | extern inline _Float128 |

127 | fabsf128 (_Float128 x) |

128 | { |

129 | return __builtin_fabsf128 (x); |

130 | } |

131 | # endif |

132 | |

133 | # if !(defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ > 0) |

134 | # ifndef NO_MATH_REDIRECT |

135 | /* Declare some functions for use within GLIBC. Compilers typically |

136 | inline those functions as a single instruction. Use an asm to |

137 | avoid use of PLTs if it doesn't. */ |

138 | # define MATH_REDIRECT(FUNC, PREFIX, ARGS) \ |

139 | float (FUNC ## f) (ARGS (float)) asm (PREFIX #FUNC "f"); \ |

140 | double (FUNC) (ARGS (double)) asm (PREFIX #FUNC ); \ |

141 | MATH_REDIRECT_LDBL (FUNC, PREFIX, ARGS) \ |

142 | MATH_REDIRECT_F128 (FUNC, PREFIX, ARGS) |

143 | # if defined __NO_LONG_DOUBLE_MATH \ |

144 | || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 |

145 | # define MATH_REDIRECT_LDBL(FUNC, PREFIX, ARGS) |

146 | # else |

147 | # define MATH_REDIRECT_LDBL(FUNC, PREFIX, ARGS) \ |

148 | long double (FUNC ## l) (ARGS (long double)) asm (PREFIX #FUNC "l"); |

149 | # endif |

150 | # if __HAVE_DISTINCT_FLOAT128 |

151 | # define MATH_REDIRECT_F128(FUNC, PREFIX, ARGS) \ |

152 | _Float128 (FUNC ## f128) (ARGS (_Float128)) asm (PREFIX #FUNC "f128"); |

153 | # else |

154 | # define MATH_REDIRECT_F128(FUNC, PREFIX, ARGS) |

155 | # endif |

156 | # define MATH_REDIRECT_UNARY_ARGS(TYPE) TYPE |

157 | # define MATH_REDIRECT_BINARY_ARGS(TYPE) TYPE, TYPE |

158 | # define MATH_REDIRECT_TERNARY_ARGS(TYPE) TYPE, TYPE, TYPE |

159 | MATH_REDIRECT (sqrt, "__ieee754_", MATH_REDIRECT_UNARY_ARGS) |

160 | MATH_REDIRECT (ceil, "__", MATH_REDIRECT_UNARY_ARGS) |

161 | MATH_REDIRECT (floor, "__", MATH_REDIRECT_UNARY_ARGS) |

162 | MATH_REDIRECT (roundeven, "__", MATH_REDIRECT_UNARY_ARGS) |

163 | MATH_REDIRECT (rint, "__", MATH_REDIRECT_UNARY_ARGS) |

164 | MATH_REDIRECT (trunc, "__", MATH_REDIRECT_UNARY_ARGS) |

165 | MATH_REDIRECT (round, "__", MATH_REDIRECT_UNARY_ARGS) |

166 | MATH_REDIRECT (copysign, "__", MATH_REDIRECT_BINARY_ARGS) |

167 | MATH_REDIRECT (fma, "__", MATH_REDIRECT_TERNARY_ARGS) |

168 | # endif |

169 | # endif |

170 | |

171 | #endif |

172 | #endif |

173 |