| 1 | use crate::float::Float; |
| 2 | use crate::int::Int; |
| 3 | |
| 4 | /// Returns `a` raised to the power `b` |
| 5 | fn pow<F: Float>(a: F, b: i32) -> F { |
| 6 | let mut a: F = a; |
| 7 | let recip: bool = b < 0; |
| 8 | let mut pow: u32 = Int::abs_diff(self:b, other:0); |
| 9 | let mut mul: F = F::ONE; |
| 10 | loop { |
| 11 | if (pow & 1) != 0 { |
| 12 | mul *= a; |
| 13 | } |
| 14 | pow >>= 1; |
| 15 | if pow == 0 { |
| 16 | break; |
| 17 | } |
| 18 | a *= a; |
| 19 | } |
| 20 | |
| 21 | if recip { |
| 22 | F::ONE / mul |
| 23 | } else { |
| 24 | mul |
| 25 | } |
| 26 | } |
| 27 | |
| 28 | intrinsics! { |
| 29 | #[avr_skip] |
| 30 | pub extern "C" fn __powisf2(a: f32, b: i32) -> f32 { |
| 31 | pow(a, b) |
| 32 | } |
| 33 | |
| 34 | #[avr_skip] |
| 35 | pub extern "C" fn __powidf2(a: f64, b: i32) -> f64 { |
| 36 | pow(a, b) |
| 37 | } |
| 38 | |
| 39 | #[avr_skip] |
| 40 | #[ppc_alias = __powikf2] |
| 41 | #[cfg (f128_enabled)] |
| 42 | // FIXME(f16_f128): MSVC cannot build these until `__divtf3` is available in nightly. |
| 43 | #[cfg (not(target_env = "msvc" ))] |
| 44 | pub extern "C" fn __powitf2(a: f128, b: i32) -> f128 { |
| 45 | pow(a, b) |
| 46 | } |
| 47 | } |
| 48 | |