| 153 | |
| 154 | #if defined(__riscv) && (__riscv_xlen == 32) |
| 155 | static FASTLED_FORCE_INLINE u16x16 lerp(u16x16 a, u16x16 b, u16x16 t) { |
| 156 | #else |
| 157 | static constexpr FASTLED_FORCE_INLINE u16x16 lerp(u16x16 a, u16x16 b, u16x16 t) FL_NOEXCEPT { |
| 158 | #endif |
| 159 | return a + (b - a) * t; |
| 160 | } |
| 161 | |
| 162 | static constexpr FASTLED_FORCE_INLINE u16x16 step(u16x16 edge, u16x16 x) FL_NOEXCEPT { |
| 163 | return x < edge ? u16x16() : u16x16(1.0f); |
| 164 | } |
| 165 | |
| 166 | static FASTLED_FORCE_INLINE u16x16 smoothstep(u16x16 edge0, u16x16 edge1, u16x16 x) FL_NOEXCEPT { |
| 167 | constexpr u16x16 zero(0.0f); |
| 168 | constexpr u16x16 one(1.0f); |
| 169 | constexpr u16x16 two(2.0f); |
| 170 | constexpr u16x16 three(3.0f); |
| 171 | u16x16 t = clamp((x - edge0) / (edge1 - edge0), zero, one); |
| 172 | return t * t * (three - two * t); |
| 173 | } |
| 174 | |
| 175 | static constexpr FASTLED_FORCE_INLINE u16x16 sqrt(u16x16 x) FL_NOEXCEPT { |
| 176 | return x.mValue == 0 ? u16x16() : from_raw(static_cast<u32>( |
| 177 | fl::isqrt64(static_cast<u64>(x.mValue) << FRAC_BITS))); |
| 178 | } |
| 179 | |
| 180 | static constexpr FASTLED_FORCE_INLINE u16x16 rsqrt(u16x16 x) FL_NOEXCEPT { |
| 181 | return sqrt(x).mValue == 0 |
| 182 | ? u16x16() |
| 183 | : from_raw(static_cast<u32>(1) << FRAC_BITS) / sqrt(x); |
| 184 | } |
| 185 | |
| 186 | static FASTLED_FORCE_INLINE u16x16 pow(u16x16 base, u16x16 exp) FL_NOEXCEPT { |
| 187 | constexpr u16x16 one(1.0f); |
| 188 | if (exp.mValue == 0) return one; |
| 189 | if (base == one) return one; |
| 190 | if (base.mValue == 0) return u16x16(); |
| 191 | // Snap base values within ~2 ULPs of 1.0 to exactly 1.0 to dodge the |
| 192 | // log2(1+t) minimax polynomial's upper-endpoint residual (#2969). |
| 193 | constexpr u32 kOneRaw = static_cast<u32>(SCALE); |
| 194 | if (base.mValue >= (kOneRaw - 2u) && base.mValue <= kOneRaw) { |
| 195 | return one; |
| 196 | } |
| 197 | return exp2_fp(exp * log2_fp(base)); |
| 198 | } |
| 199 | |
| 200 | private: |
| 201 | u32 mValue = 0; |
| 202 | |
| 203 | // Returns 0-based position of highest set bit, or -1 if v==0. |
| 204 | static constexpr FASTLED_FORCE_INLINE int highest_bit(u32 v) FL_NOEXCEPT { |
| 205 | return v == 0 ? -1 : _highest_bit_step(v, 0); |
| 206 | } |
| 207 | |
| 208 | static constexpr int _highest_bit_step(u32 v, int r) FL_NOEXCEPT { |
| 209 | return (v & 0xFFFF0000u) ? _highest_bit_step(v >> 16, r + 16) |
| 210 | : (v & 0x0000FF00u) ? _highest_bit_step(v >> 8, r + 8) |
| 211 | : (v & 0x000000F0u) ? _highest_bit_step(v >> 4, r + 4) |
| 212 | : (v & 0x0000000Cu) ? _highest_bit_step(v >> 2, r + 2) |
no test coverage detected