1 | macro_rules! force_eval { |
2 | ($e:expr) => { |
3 | unsafe { ::core::ptr::read_volatile(&$e) } |
4 | }; |
5 | } |
6 | |
7 | #[cfg (not(debug_assertions))] |
8 | macro_rules! i { |
9 | ($array:expr, $index:expr) => { |
10 | unsafe { *$array.get_unchecked($index) } |
11 | }; |
12 | ($array:expr, $index:expr, = , $rhs:expr) => { |
13 | unsafe { |
14 | *$array.get_unchecked_mut($index) = $rhs; |
15 | } |
16 | }; |
17 | ($array:expr, $index:expr, += , $rhs:expr) => { |
18 | unsafe { |
19 | *$array.get_unchecked_mut($index) += $rhs; |
20 | } |
21 | }; |
22 | ($array:expr, $index:expr, -= , $rhs:expr) => { |
23 | unsafe { |
24 | *$array.get_unchecked_mut($index) -= $rhs; |
25 | } |
26 | }; |
27 | ($array:expr, $index:expr, &= , $rhs:expr) => { |
28 | unsafe { |
29 | *$array.get_unchecked_mut($index) &= $rhs; |
30 | } |
31 | }; |
32 | ($array:expr, $index:expr, == , $rhs:expr) => { |
33 | unsafe { *$array.get_unchecked_mut($index) == $rhs } |
34 | }; |
35 | } |
36 | |
37 | #[cfg (debug_assertions)] |
38 | macro_rules! i { |
39 | ($array:expr, $index:expr) => { |
40 | *$array.get($index).unwrap() |
41 | }; |
42 | ($array:expr, $index:expr, = , $rhs:expr) => { |
43 | *$array.get_mut($index).unwrap() = $rhs; |
44 | }; |
45 | ($array:expr, $index:expr, -= , $rhs:expr) => { |
46 | *$array.get_mut($index).unwrap() -= $rhs; |
47 | }; |
48 | ($array:expr, $index:expr, += , $rhs:expr) => { |
49 | *$array.get_mut($index).unwrap() += $rhs; |
50 | }; |
51 | ($array:expr, $index:expr, &= , $rhs:expr) => { |
52 | *$array.get_mut($index).unwrap() &= $rhs; |
53 | }; |
54 | ($array:expr, $index:expr, == , $rhs:expr) => { |
55 | *$array.get_mut($index).unwrap() == $rhs |
56 | }; |
57 | } |
58 | |
59 | // Temporary macro to avoid panic codegen for division (in debug mode too). At |
60 | // the time of this writing this is only used in a few places, and once |
61 | // rust-lang/rust#72751 is fixed then this macro will no longer be necessary and |
62 | // the native `/` operator can be used and panics won't be codegen'd. |
63 | #[cfg (any(debug_assertions, not(intrinsics_enabled)))] |
64 | macro_rules! div { |
65 | ($a:expr, $b:expr) => { |
66 | $a / $b |
67 | }; |
68 | } |
69 | |
70 | #[cfg (all(not(debug_assertions), intrinsics_enabled))] |
71 | macro_rules! div { |
72 | ($a:expr, $b:expr) => { |
73 | unsafe { core::intrinsics::unchecked_div($a, $b) } |
74 | }; |
75 | } |
76 | |
77 | // `support` may be public for testing |
78 | #[macro_use ] |
79 | #[cfg (feature = "unstable-public-internals" )] |
80 | pub mod support; |
81 | |
82 | #[macro_use ] |
83 | #[cfg (not(feature = "unstable-public-internals" ))] |
84 | pub(crate) mod support; |
85 | |
86 | cfg_if! { |
87 | if #[cfg(feature = "unstable-public-internals" )] { |
88 | pub mod generic; |
89 | } else { |
90 | mod generic; |
91 | } |
92 | } |
93 | |
94 | // Private modules |
95 | mod arch; |
96 | mod expo2; |
97 | mod k_cos; |
98 | mod k_cosf; |
99 | mod k_expo2; |
100 | mod k_expo2f; |
101 | mod k_sin; |
102 | mod k_sinf; |
103 | mod k_tan; |
104 | mod k_tanf; |
105 | mod rem_pio2; |
106 | mod rem_pio2_large; |
107 | mod rem_pio2f; |
108 | |
109 | // Private re-imports |
110 | use self::expo2::expo2; |
111 | use self::k_cos::k_cos; |
112 | use self::k_cosf::k_cosf; |
113 | use self::k_expo2::k_expo2; |
114 | use self::k_expo2f::k_expo2f; |
115 | use self::k_sin::k_sin; |
116 | use self::k_sinf::k_sinf; |
117 | use self::k_tan::k_tan; |
118 | use self::k_tanf::k_tanf; |
119 | use self::rem_pio2::rem_pio2; |
120 | use self::rem_pio2_large::rem_pio2_large; |
121 | use self::rem_pio2f::rem_pio2f; |
122 | #[allow (unused_imports)] |
123 | use self::support::{CastFrom, CastInto, DFloat, DInt, Float, HFloat, HInt, Int, IntTy, MinInt}; |
124 | |
125 | // Public modules |
126 | mod acos; |
127 | mod acosf; |
128 | mod acosh; |
129 | mod acoshf; |
130 | mod asin; |
131 | mod asinf; |
132 | mod asinh; |
133 | mod asinhf; |
134 | mod atan; |
135 | mod atan2; |
136 | mod atan2f; |
137 | mod atanf; |
138 | mod atanh; |
139 | mod atanhf; |
140 | mod cbrt; |
141 | mod cbrtf; |
142 | mod ceil; |
143 | mod ceilf; |
144 | mod copysign; |
145 | mod copysignf; |
146 | mod cos; |
147 | mod cosf; |
148 | mod cosh; |
149 | mod coshf; |
150 | mod erf; |
151 | mod erff; |
152 | mod exp; |
153 | mod exp10; |
154 | mod exp10f; |
155 | mod exp2; |
156 | mod exp2f; |
157 | mod expf; |
158 | mod expm1; |
159 | mod expm1f; |
160 | mod fabs; |
161 | mod fabsf; |
162 | mod fdim; |
163 | mod fdimf; |
164 | mod floor; |
165 | mod floorf; |
166 | mod fma; |
167 | mod fma_wide; |
168 | mod fmin_fmax; |
169 | mod fminimum_fmaximum; |
170 | mod fminimum_fmaximum_num; |
171 | mod fmod; |
172 | mod fmodf; |
173 | mod frexp; |
174 | mod frexpf; |
175 | mod hypot; |
176 | mod hypotf; |
177 | mod ilogb; |
178 | mod ilogbf; |
179 | mod j0; |
180 | mod j0f; |
181 | mod j1; |
182 | mod j1f; |
183 | mod jn; |
184 | mod jnf; |
185 | mod ldexp; |
186 | mod ldexpf; |
187 | mod lgamma; |
188 | mod lgamma_r; |
189 | mod lgammaf; |
190 | mod lgammaf_r; |
191 | mod log; |
192 | mod log10; |
193 | mod log10f; |
194 | mod log1p; |
195 | mod log1pf; |
196 | mod log2; |
197 | mod log2f; |
198 | mod logf; |
199 | mod modf; |
200 | mod modff; |
201 | mod nextafter; |
202 | mod nextafterf; |
203 | mod pow; |
204 | mod powf; |
205 | mod remainder; |
206 | mod remainderf; |
207 | mod remquo; |
208 | mod remquof; |
209 | mod rint; |
210 | mod round; |
211 | mod roundeven; |
212 | mod roundf; |
213 | mod scalbn; |
214 | mod scalbnf; |
215 | mod sin; |
216 | mod sincos; |
217 | mod sincosf; |
218 | mod sinf; |
219 | mod sinh; |
220 | mod sinhf; |
221 | mod sqrt; |
222 | mod sqrtf; |
223 | mod tan; |
224 | mod tanf; |
225 | mod tanh; |
226 | mod tanhf; |
227 | mod tgamma; |
228 | mod tgammaf; |
229 | mod trunc; |
230 | mod truncf; |
231 | |
232 | // Use separated imports instead of {}-grouped imports for easier merging. |
233 | pub use self::acos::acos; |
234 | pub use self::acosf::acosf; |
235 | pub use self::acosh::acosh; |
236 | pub use self::acoshf::acoshf; |
237 | pub use self::asin::asin; |
238 | pub use self::asinf::asinf; |
239 | pub use self::asinh::asinh; |
240 | pub use self::asinhf::asinhf; |
241 | pub use self::atan::atan; |
242 | pub use self::atan2::atan2; |
243 | pub use self::atan2f::atan2f; |
244 | pub use self::atanf::atanf; |
245 | pub use self::atanh::atanh; |
246 | pub use self::atanhf::atanhf; |
247 | pub use self::cbrt::cbrt; |
248 | pub use self::cbrtf::cbrtf; |
249 | pub use self::ceil::ceil; |
250 | pub use self::ceilf::ceilf; |
251 | pub use self::copysign::copysign; |
252 | pub use self::copysignf::copysignf; |
253 | pub use self::cos::cos; |
254 | pub use self::cosf::cosf; |
255 | pub use self::cosh::cosh; |
256 | pub use self::coshf::coshf; |
257 | pub use self::erf::{erf, erfc}; |
258 | pub use self::erff::{erfcf, erff}; |
259 | pub use self::exp::exp; |
260 | pub use self::exp2::exp2; |
261 | pub use self::exp2f::exp2f; |
262 | pub use self::exp10::exp10; |
263 | pub use self::exp10f::exp10f; |
264 | pub use self::expf::expf; |
265 | pub use self::expm1::expm1; |
266 | pub use self::expm1f::expm1f; |
267 | pub use self::fabs::fabs; |
268 | pub use self::fabsf::fabsf; |
269 | pub use self::fdim::fdim; |
270 | pub use self::fdimf::fdimf; |
271 | pub use self::floor::floor; |
272 | pub use self::floorf::floorf; |
273 | pub use self::fma::fma; |
274 | pub use self::fma_wide::fmaf; |
275 | pub use self::fmin_fmax::{fmax, fmaxf, fmin, fminf}; |
276 | pub use self::fminimum_fmaximum::{fmaximum, fmaximumf, fminimum, fminimumf}; |
277 | pub use self::fminimum_fmaximum_num::{fmaximum_num, fmaximum_numf, fminimum_num, fminimum_numf}; |
278 | pub use self::fmod::fmod; |
279 | pub use self::fmodf::fmodf; |
280 | pub use self::frexp::frexp; |
281 | pub use self::frexpf::frexpf; |
282 | pub use self::hypot::hypot; |
283 | pub use self::hypotf::hypotf; |
284 | pub use self::ilogb::ilogb; |
285 | pub use self::ilogbf::ilogbf; |
286 | pub use self::j0::{j0, y0}; |
287 | pub use self::j0f::{j0f, y0f}; |
288 | pub use self::j1::{j1, y1}; |
289 | pub use self::j1f::{j1f, y1f}; |
290 | pub use self::jn::{jn, yn}; |
291 | pub use self::jnf::{jnf, ynf}; |
292 | pub use self::ldexp::ldexp; |
293 | pub use self::ldexpf::ldexpf; |
294 | pub use self::lgamma::lgamma; |
295 | pub use self::lgamma_r::lgamma_r; |
296 | pub use self::lgammaf::lgammaf; |
297 | pub use self::lgammaf_r::lgammaf_r; |
298 | pub use self::log::log; |
299 | pub use self::log1p::log1p; |
300 | pub use self::log1pf::log1pf; |
301 | pub use self::log2::log2; |
302 | pub use self::log2f::log2f; |
303 | pub use self::log10::log10; |
304 | pub use self::log10f::log10f; |
305 | pub use self::logf::logf; |
306 | pub use self::modf::modf; |
307 | pub use self::modff::modff; |
308 | pub use self::nextafter::nextafter; |
309 | pub use self::nextafterf::nextafterf; |
310 | pub use self::pow::pow; |
311 | pub use self::powf::powf; |
312 | pub use self::remainder::remainder; |
313 | pub use self::remainderf::remainderf; |
314 | pub use self::remquo::remquo; |
315 | pub use self::remquof::remquof; |
316 | pub use self::rint::{rint, rintf}; |
317 | pub use self::round::round; |
318 | pub use self::roundeven::{roundeven, roundevenf}; |
319 | pub use self::roundf::roundf; |
320 | pub use self::scalbn::scalbn; |
321 | pub use self::scalbnf::scalbnf; |
322 | pub use self::sin::sin; |
323 | pub use self::sincos::sincos; |
324 | pub use self::sincosf::sincosf; |
325 | pub use self::sinf::sinf; |
326 | pub use self::sinh::sinh; |
327 | pub use self::sinhf::sinhf; |
328 | pub use self::sqrt::sqrt; |
329 | pub use self::sqrtf::sqrtf; |
330 | pub use self::tan::tan; |
331 | pub use self::tanf::tanf; |
332 | pub use self::tanh::tanh; |
333 | pub use self::tanhf::tanhf; |
334 | pub use self::tgamma::tgamma; |
335 | pub use self::tgammaf::tgammaf; |
336 | pub use self::trunc::trunc; |
337 | pub use self::truncf::truncf; |
338 | |
339 | cfg_if! { |
340 | if #[cfg(f16_enabled)] { |
341 | // verify-sorted-start |
342 | mod ceilf16; |
343 | mod copysignf16; |
344 | mod fabsf16; |
345 | mod fdimf16; |
346 | mod floorf16; |
347 | mod fmodf16; |
348 | mod ldexpf16; |
349 | mod roundf16; |
350 | mod scalbnf16; |
351 | mod sqrtf16; |
352 | mod truncf16; |
353 | // verify-sorted-end |
354 | |
355 | // verify-sorted-start |
356 | pub use self::ceilf16::ceilf16; |
357 | pub use self::copysignf16::copysignf16; |
358 | pub use self::fabsf16::fabsf16; |
359 | pub use self::fdimf16::fdimf16; |
360 | pub use self::floorf16::floorf16; |
361 | pub use self::fmin_fmax::{fmaxf16, fminf16}; |
362 | pub use self::fminimum_fmaximum::{fmaximumf16, fminimumf16}; |
363 | pub use self::fminimum_fmaximum_num::{fmaximum_numf16, fminimum_numf16}; |
364 | pub use self::fmodf16::fmodf16; |
365 | pub use self::ldexpf16::ldexpf16; |
366 | pub use self::rint::rintf16; |
367 | pub use self::roundeven::roundevenf16; |
368 | pub use self::roundf16::roundf16; |
369 | pub use self::scalbnf16::scalbnf16; |
370 | pub use self::sqrtf16::sqrtf16; |
371 | pub use self::truncf16::truncf16; |
372 | // verify-sorted-end |
373 | |
374 | #[allow(unused_imports)] |
375 | pub(crate) use self::fma_wide::fmaf16; |
376 | } |
377 | } |
378 | |
379 | cfg_if! { |
380 | if #[cfg(f128_enabled)] { |
381 | // verify-sorted-start |
382 | mod ceilf128; |
383 | mod copysignf128; |
384 | mod fabsf128; |
385 | mod fdimf128; |
386 | mod floorf128; |
387 | mod fmodf128; |
388 | mod ldexpf128; |
389 | mod roundf128; |
390 | mod scalbnf128; |
391 | mod sqrtf128; |
392 | mod truncf128; |
393 | // verify-sorted-end |
394 | |
395 | // verify-sorted-start |
396 | pub use self::ceilf128::ceilf128; |
397 | pub use self::copysignf128::copysignf128; |
398 | pub use self::fabsf128::fabsf128; |
399 | pub use self::fdimf128::fdimf128; |
400 | pub use self::floorf128::floorf128; |
401 | pub use self::fma::fmaf128; |
402 | pub use self::fmin_fmax::{fmaxf128, fminf128}; |
403 | pub use self::fminimum_fmaximum::{fmaximumf128, fminimumf128}; |
404 | pub use self::fminimum_fmaximum_num::{fmaximum_numf128, fminimum_numf128}; |
405 | pub use self::fmodf128::fmodf128; |
406 | pub use self::ldexpf128::ldexpf128; |
407 | pub use self::rint::rintf128; |
408 | pub use self::roundeven::roundevenf128; |
409 | pub use self::roundf128::roundf128; |
410 | pub use self::scalbnf128::scalbnf128; |
411 | pub use self::sqrtf128::sqrtf128; |
412 | pub use self::truncf128::truncf128; |
413 | // verify-sorted-end |
414 | } |
415 | } |
416 | |
417 | #[inline ] |
418 | fn get_high_word(x: f64) -> u32 { |
419 | (x.to_bits() >> 32) as u32 |
420 | } |
421 | |
422 | #[inline ] |
423 | fn get_low_word(x: f64) -> u32 { |
424 | x.to_bits() as u32 |
425 | } |
426 | |
427 | #[inline ] |
428 | fn with_set_high_word(f: f64, hi: u32) -> f64 { |
429 | let mut tmp: u64 = f.to_bits(); |
430 | tmp &= 0x00000000_ffffffff; |
431 | tmp |= (hi as u64) << 32; |
432 | f64::from_bits(tmp) |
433 | } |
434 | |
435 | #[inline ] |
436 | fn with_set_low_word(f: f64, lo: u32) -> f64 { |
437 | let mut tmp: u64 = f.to_bits(); |
438 | tmp &= 0xffffffff_00000000; |
439 | tmp |= lo as u64; |
440 | f64::from_bits(tmp) |
441 | } |
442 | |
443 | #[inline ] |
444 | fn combine_words(hi: u32, lo: u32) -> f64 { |
445 | f64::from_bits(((hi as u64) << 32) | lo as u64) |
446 | } |
447 | |