mirror of
https://github.com/minetest/irrlicht.git
synced 2024-11-03 00:40:41 +01:00
3280b3319e
To avoid changing burnings now those functions have no IRRLICHT_FAST_MATH anymore, there's a new header irrMathFastCompat.h which has ..._fast functions doing the old behavior. With the troubles they have documented. I changed burnings to use those functions throughout. Or as much as possible... Burnings probably also uses classes like SColor which also have functions using those, but I don't plan to adapt them. Maybe IRRLICHT_FAST_MATH should be a flag exlusive to burnings in the future, I don't think it makes much sense otherwise anymore (it often expects 32-bit asm). git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6012 dfc29bdd-3216-0410-991c-e03cc46cb475
127 lines
2.7 KiB
C++
127 lines
2.7 KiB
C++
// 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__
|