From b05f813e70070afdeed774c512c09aa7d04951d2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 9 Dec 2013 14:13:37 +0100 Subject: [PATCH] Added NzMultiplyAdd Use hardware FMA (or at least faster FMA) when possible Former-commit-id: fd5134d2aebe924fb8c9148224101dd7d340bb5f --- include/Nazara/Math/Basic.hpp | 1 + include/Nazara/Math/Basic.inl | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/include/Nazara/Math/Basic.hpp b/include/Nazara/Math/Basic.hpp index 212b72703..87a3df26a 100644 --- a/include/Nazara/Math/Basic.hpp +++ b/include/Nazara/Math/Basic.hpp @@ -24,6 +24,7 @@ template T NzApproach(T value, T objective, T increment); template T NzClamp(T value, T min, T max); template T NzDegrees(T degrees); template T NzDegreeToRadian(T degrees); +template T NzMultiplyAdd(T x, T y, T z); unsigned int NzIntegralPow(unsigned int base, unsigned int exponent); unsigned int NzGetNearestPowerOfTwo(unsigned int number); unsigned int NzGetNumberLength(signed char number); diff --git a/include/Nazara/Math/Basic.inl b/include/Nazara/Math/Basic.inl index 6a4c16e8d..0b1caa417 100644 --- a/include/Nazara/Math/Basic.inl +++ b/include/Nazara/Math/Basic.inl @@ -50,6 +50,36 @@ T NzDegreeToRadian(T degrees) return degrees * F(M_PI/180.0); } +template +T NzMultiplyAdd(T x, T y, T z) +{ + return x*y + z; +} + +#ifdef FP_FAST_FMAF +template<> +inline float NzMultiplyAdd(float x, float y, float z) +{ + return std::fmaf(x, y, z); +} +#endif + +#ifdef FP_FAST_FMA +template<> +inline double NzMultiplyAdd(double x, double y, double z) +{ + return std::fma(x, y, z); +} +#endif + +#ifdef FP_FAST_FMAL +template<> +inline long double NzMultiplyAdd(long double x, long double y, long double z) +{ + return std::fmal(x, y, z); +} +#endif + inline unsigned int NzIntegralPow(unsigned int base, unsigned int exponent) { unsigned int r = 1;