diff options
author | Hendiadyoin1 <leon2002.la@gmail.com> | 2022-02-03 12:48:17 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-15 11:39:42 +0100 |
commit | cd21e0322510bdd95c5d53075f80c49efcb2f24d (patch) | |
tree | c735ef5b046067f3da5fd961b6b74600451b4b5b | |
parent | 47fe911196b5551f5b4a829a1a310ca66cf12e99 (diff) | |
download | serenity-cd21e0322510bdd95c5d53075f80c49efcb2f24d.zip |
AK+Everywhere: Add sincos and use it in some places
Calculating sin and cos at once is quite a bit cheaper than calculating
them individually.
x87 has even a dedicated instruction for it: `fsincos`.
-rw-r--r-- | AK/Complex.h | 4 | ||||
-rw-r--r-- | AK/Math.h | 15 | ||||
-rw-r--r-- | Userland/DevTools/UserspaceEmulator/SoftFPU.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibAudio/Sample.h | 10 | ||||
-rw-r--r-- | Userland/Libraries/LibDSP/FFT.h | 5 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/Matrix4x4.h | 4 |
6 files changed, 30 insertions, 10 deletions
diff --git a/AK/Complex.h b/AK/Complex.h index b9deb170f9..728ae33c77 100644 --- a/AK/Complex.h +++ b/AK/Complex.h @@ -55,7 +55,9 @@ public: template<AK::Concepts::Arithmetic U, AK::Concepts::Arithmetic V> static constexpr Complex<T> from_polar(U magnitude, V phase) { - return Complex<T>(magnitude * cos(phase), magnitude * sin(phase)); + V s, c; + sincos(phase, s, c); + return Complex<T>(magnitude * c, magnitude * s); } template<AK::Concepts::Arithmetic U> @@ -204,6 +204,20 @@ constexpr T cos(T angle) } template<FloatingPoint T> +constexpr void sincos(T angle, T& sin_val, T& cos_val) +{ + if (is_constant_evaluated()) { + sin_val = sin(angle); + cos_val = cos(angle); + return; + } + asm( + "fsincos" + : "=t"(cos_val), "=u"(sin_val) + : "0"(angle)); +} + +template<FloatingPoint T> constexpr T tan(T angle) { CONSTEXPR_STATE(tan, angle); @@ -303,6 +317,7 @@ using Trigonometry::atan2; using Trigonometry::cos; using Trigonometry::hypot; using Trigonometry::sin; +using Trigonometry::sincos; using Trigonometry::tan; namespace Exponentials { diff --git a/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp b/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp index 61ec8de3cb..a5146a13e0 100644 --- a/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp +++ b/Userland/DevTools/UserspaceEmulator/SoftFPU.cpp @@ -36,7 +36,7 @@ ALWAYS_INLINE void warn_if_uninitialized(T value_with_shadow, const char* messag } } -namespace UserspaceEmulator { +namespace UserspaceEmulator { // NOLINT(readability-implicit-bool-conversion) 0/1 to follow spec closer ALWAYS_INLINE void SoftFPU::warn_if_mmx_absolute(u8 index) const { diff --git a/Userland/Libraries/LibAudio/Sample.h b/Userland/Libraries/LibAudio/Sample.h index ec52cd90c1..b3b5e57e2f 100644 --- a/Userland/Libraries/LibAudio/Sample.h +++ b/Userland/Libraries/LibAudio/Sample.h @@ -97,8 +97,10 @@ struct Sample { double const pi_over_2 = AK::Pi<double> * 0.5; double const root_over_2 = AK::sqrt(2.0) * 0.5; double const angle = position * pi_over_2 * 0.5; - left *= root_over_2 * (AK::cos(angle) - AK::sin(angle)); - right *= root_over_2 * (AK::cos(angle) + AK::sin(angle)); + double s, c; + AK::sincos(angle, s, c); + left *= root_over_2 * (c - s); + right *= root_over_2 * (c + s); return *this; } @@ -116,7 +118,7 @@ struct Sample { return *this; } - constexpr Sample operator*(double const mult) + constexpr Sample operator*(double const mult) const { return { left * mult, right * mult }; } @@ -134,7 +136,7 @@ struct Sample { return *this; } - constexpr Sample operator+(Sample const& other) + constexpr Sample operator+(Sample const& other) const { return { left + other.left, right + other.right }; } diff --git a/Userland/Libraries/LibDSP/FFT.h b/Userland/Libraries/LibDSP/FFT.h index c9db991b1d..faf0af84c0 100644 --- a/Userland/Libraries/LibDSP/FFT.h +++ b/Userland/Libraries/LibDSP/FFT.h @@ -28,11 +28,12 @@ constexpr void fft(Span<Complex<double>> sample_data, bool invert = false) for (int len = 2; len <= n; len <<= 1) { double ang = 2 * AK::Pi<double> / len * (invert ? -1 : 1); - Complex<double> wlen(AK::cos(ang), AK::sin(ang)); + Complex<double> wlen = Complex<double>::from_polar(1., ang); for (int i = 0; i < n; i += len) { Complex<double> w = { 1., 0. }; for (int j = 0; j < len / 2; j++) { - Complex<double> u = sample_data[i + j], v = sample_data[i + j + len / 2] * w; + Complex<double> u = sample_data[i + j]; + Complex<double> v = sample_data[i + j + len / 2] * w; sample_data[i + j] = u + v; sample_data[i + j + len / 2] = u - v; w *= wlen; diff --git a/Userland/Libraries/LibGfx/Matrix4x4.h b/Userland/Libraries/LibGfx/Matrix4x4.h index 4637f4e816..4e0c6dda8c 100644 --- a/Userland/Libraries/LibGfx/Matrix4x4.h +++ b/Userland/Libraries/LibGfx/Matrix4x4.h @@ -70,8 +70,8 @@ constexpr static Matrix4x4<T> scale_matrix(const Vector3<T>& s) template<typename T> constexpr static Matrix4x4<T> rotation_matrix(const Vector3<T>& axis, T angle) { - T c = AK::cos(angle); - T s = AK::sin(angle); + T c, s; + AK::sincos(angle, s, c); T t = 1 - c; T x = axis.x(); T y = axis.y(); |