// This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in irrlicht.h #ifndef __IRR_FAST_MATH_COMPAT_H_INCLUDED__ #define __IRR_FAST_MATH_COMPAT_H_INCLUDED__ #include "irrMath.h" namespace irr { namespace core { // IRRLICHT_FAST_MATH functions which I wanted to kick out because they return // wrong results. But last time I proposed that I've been asked to keep them for // Burnings software renderer. So to avoid changing that accidentally or messing up // it's speed I'll keep them around, but only as internal header. // They should not be used otherwise any longer. // Some examples for unexpected results when using this with IRRLICHT_FAST_MATH: // Input 1, expected 1, got 0 // Input 3, expected 3, got 2 // Input -1.40129846e-45, expected -1, got 0 REALINLINE s32 floor32_fast(f32 x) { #ifdef IRRLICHT_FAST_MATH const f32 h = 0.5f; s32 t; #if defined(_MSC_VER) && !defined(_WIN64) __asm { fld x fsub h fistp t } #elif defined(__GNUC__) __asm__ __volatile__ ( "fsub %2 \n\t" "fistpl %0" : "=m" (t) : "t" (x), "f" (h) : "st" ); #else return (s32) floorf ( x ); #endif return t; #else // no fast math return (s32) floorf ( x ); #endif } // Some examples for unexpected results when using this with IRRLICHT_FAST_MATH: // Input 1.40129846e-45, expected 1, got 0 // Input -1, expected -1, got 0 // Input -3, expected -3, got -2 REALINLINE s32 ceil32_fast ( f32 x ) { #ifdef IRRLICHT_FAST_MATH const f32 h = 0.5f; s32 t; #if defined(_MSC_VER) && !defined(_WIN64) __asm { fld x fadd h fistp t } #elif defined(__GNUC__) __asm__ __volatile__ ( "fadd %2 \n\t" "fistpl %0 \n\t" : "=m"(t) : "t"(x), "f"(h) : "st" ); #else return (s32) ceilf ( x ); #endif return t; #else // not fast math return (s32) ceilf ( x ); #endif } // Some examples for unexpected results when using this with IRRLICHT_FAST_MATH: // Input 0.5, expected 1, got 0 // Input 2.5, expected 3, got 2 // Input -1.40129846e-45, expected -nan(ind), got -inf // Input -2.80259693e-45, expected -nan(ind), got -inf REALINLINE s32 round32_fast(f32 x) { #if defined(IRRLICHT_FAST_MATH) s32 t; #if defined(_MSC_VER) && !defined(_WIN64) __asm { fld x fistp t } #elif defined(__GNUC__) __asm__ __volatile__ ( "fistpl %0 \n\t" : "=m"(t) : "t"(x) : "st" ); #else return (s32) round_(x); #endif return t; #else // no fast math return (s32) round_(x); #endif } } // end namespace core } // end namespace irr #endif // __IRR_FAST_MATH_COMPAT_H_INCLUDED__