28 #ifndef itkMathDetail_h
29 #define itkMathDetail_h
31 #include "vnl/vnl_math.h"
35 #ifdef ITK_HAVE_FENV_H
42 #if defined( ITK_HAVE_EMMINTRIN_H ) && !defined( ITK_WRAPPING_PARSER )
43 #include <emmintrin.h>
47 #define USE_SSE2_64IMPL 0
48 #define USE_SSE2_32IMPL 0
52 #if defined(__APPLE__) && defined( __SSE2__ ) && !defined( ITK_WRAPPING_PARSER )
54 # if defined( __i386__ )
55 # undef USE_SSE2_32IMPL
56 # define USE_SSE2_32IMPL 1
59 # if defined( __x86_64 )
61 # undef USE_SSE2_64IMPL
62 # define USE_SSE2_64IMPL 1
65 # undef USE_SSE2_32IMPL
66 # define USE_SSE2_32IMPL 1
75 # if defined(ITK_COMPILER_SUPPORTS_SSE2_32) && !defined( ITK_WRAPPING_PARSER )
76 # undef USE_SSE2_32IMPL
77 # define USE_SSE2_32IMPL 1
79 # if defined(ITK_COMPILER_SUPPORTS_SSE2_64) && !defined( ITK_WRAPPING_PARSER )
80 # undef USE_SSE2_64IMPL
81 # define USE_SSE2_64IMPL 1
90 #if defined( __GNUC__ ) && ( !defined( ITK_WRAPPING_PARSER ) ) && ( defined( __i386__ ) || defined( __i386 ) \
91 || defined( __x86_64__ ) || defined( __x86_64 ) )
92 #define GCC_USE_ASM_32IMPL 1
93 #define GCC_USE_ASM_64IMPL 1
95 #define GCC_USE_ASM_32IMPL 0
96 #define GCC_USE_ASM_64IMPL 0
99 #if defined( VCL_VC ) && ( !defined( ITK_WRAPPING_PARSER ) ) && !defined( _WIN64 )
100 #define VC_USE_ASM_32IMPL 1
101 #define VC_USE_ASM_64IMPL 1
103 #define VC_USE_ASM_32IMPL 0
104 #define VC_USE_ASM_64IMPL 0
122 CLANG_SUPPRESS_Wfloat_equal
124 template<
typename TReturn,
typename TInput >
129 x +=
static_cast< TInput
>( 0.5 );
133 x -=
static_cast< TInput
>( 0.5 );
136 const TReturn r =
static_cast< TReturn
>( x );
137 return ( x != static_cast< TInput >( r ) ) ? r : static_cast< TReturn >( 2 * ( r / 2 ) );
140 template<
typename TReturn,
typename TInput >
143 x +=
static_cast< TInput
>( 0.5 );
144 const TReturn r =
static_cast< TReturn
>( x );
147 ( x == static_cast< TInput >( r ) ? r : r -
static_cast< TReturn
>( 1 ) );
150 template<
typename TReturn,
typename TInput >
153 const TReturn r =
static_cast< TReturn
>( x );
157 ( x == static_cast< TInput >( r ) ? r : r -
static_cast< TReturn
>( 1 ) );
160 template<
typename TReturn,
typename TInput >
163 const TReturn r =
static_cast< TReturn
>( x );
167 ( x == static_cast< TInput >( r ) ? r : r +
static_cast< TReturn
>( 1 ) );
175 #if USE_SSE2_32IMPL // sse2 implementation
179 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
180 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
182 return _mm_cvtsd_si32( _mm_set_sd(x) );
187 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
188 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
190 return _mm_cvtss_si32( _mm_set_ss(x) );
193 #elif GCC_USE_ASM_32IMPL // gcc asm implementation
197 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
198 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
201 __asm__ __volatile__ (
"fistpl %0" :
"=m" ( r ) :
"t" ( x ) :
"st" );
207 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
208 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
211 __asm__ __volatile__ (
"fistpl %0" :
"=m" ( r ) :
"t" ( x ) :
"st" );
215 #elif VC_USE_ASM_32IMPL // msvc asm implementation
219 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
220 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
233 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
234 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
245 #else // Base implementation
252 #if USE_SSE2_32IMPL || GCC_USE_ASM_32IMPL || VC_USE_ASM_32IMPL
263 #else // Base implementation
274 #endif // USE_SSE2_32IMPL || GCC_USE_ASM_32IMPL || VC_USE_ASM_32IMPL
279 #if USE_SSE2_64IMPL // sse2 implementation
283 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
284 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
286 return _mm_cvtsd_si64( _mm_set_sd(x) );
291 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
292 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
294 return _mm_cvtss_si64( _mm_set_ss(x) );
297 #elif GCC_USE_ASM_64IMPL // gcc asm implementation
301 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
302 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
305 __asm__ __volatile__ (
"fistpll %0" :
"=m" ( r ) :
"t" ( x ) :
"st" );
311 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
312 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
315 __asm__ __volatile__ (
"fistpll %0" :
"=m" ( r ) :
"t" ( x ) :
"st" );
319 #elif VC_USE_ASM_64IMPL // msvc asm implementation
323 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
324 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
337 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
338 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
349 #else // Base implementation
356 #if USE_SSE2_64IMPL || GCC_USE_ASM_64IMPL || VC_USE_ASM_64IMPL
367 #else // Base implementation
378 #endif // USE_SSE2_64IMPL || GCC_USE_ASM_64IMPL || VC_USE_ASM_64IMPL
380 template <
typename T>
397 template <
typename T>
425 template<
typename T >
434 #undef USE_SSE2_32IMPL
435 #undef GCC_USE_ASM_32IMPL
436 #undef VC_USE_ASM_32IMPL
438 #undef USE_SSE2_64IMPL
439 #undef GCC_USE_ASM_64IMPL
440 #undef VC_USE_ASM_64IMPL
442 #endif // end of itkMathDetail.h
int64_t RoundHalfIntegerUp_64(double x)
int32_t Ceil_32(double x)
CLANG_PRAGMA_PUSH CLANG_SUPPRESS_Wfloat_equal TReturn RoundHalfIntegerToEven_base(TInput x)
TReturn Ceil_base(TInput x)
CLANG_PRAGMA_POP int32_t RoundHalfIntegerToEven_32(double x)
KWIML_INT_uint32_t uint32_t
KWIML_INT_int64_t int64_t
int64_t Floor_64(double x)
TReturn RoundHalfIntegerUp_base(TInput x)
int64_t Ceil_64(double x)
FloatIEEETraits< T >::IntType IntType
KWIML_INT_uint64_t uint64_t
FloatIEEETraits< T >::UIntType UIntType
Define additional traits for native types such as int or float.
int64_t RoundHalfIntegerToEven_64(double x)
KWIML_INT_int32_t int32_t
TReturn Floor_base(TInput x)
int32_t Floor_32(double x)
int32_t RoundHalfIntegerUp_32(double x)