28 #ifndef itkMathDetail_h
29 #define itkMathDetail_h
34 #ifdef ITK_HAVE_FENV_H
41 #if defined( ITK_HAVE_EMMINTRIN_H ) && !defined( ITK_WRAPPING_PARSER )
42 #include <emmintrin.h>
46 #define USE_SSE2_64IMPL 0
47 #define USE_SSE2_32IMPL 0
51 #if defined(__APPLE__) && defined( __SSE2__ ) && !defined( ITK_WRAPPING_PARSER )
53 # if defined( __i386__ )
54 # undef USE_SSE2_32IMPL
55 # define USE_SSE2_32IMPL 1
58 # if defined( __x86_64 )
60 # undef USE_SSE2_64IMPL
61 # define USE_SSE2_64IMPL 1
64 # undef USE_SSE2_32IMPL
65 # define USE_SSE2_32IMPL 1
74 # if defined(ITK_COMPILER_SUPPORTS_SSE2_32) && !defined( ITK_WRAPPING_PARSER )
75 # undef USE_SSE2_32IMPL
76 # define USE_SSE2_32IMPL 1
78 # if defined(ITK_COMPILER_SUPPORTS_SSE2_64) && !defined( ITK_WRAPPING_PARSER )
79 # undef USE_SSE2_64IMPL
80 # define USE_SSE2_64IMPL 1
89 #if defined( __GNUC__ ) && ( !defined( ITK_WRAPPING_PARSER ) ) && ( defined( __i386__ ) || defined( __i386 ) \
90 || defined( __x86_64__ ) || defined( __x86_64 ) )
91 #define GCC_USE_ASM_32IMPL 1
92 #define GCC_USE_ASM_64IMPL 1
94 #define GCC_USE_ASM_32IMPL 0
95 #define GCC_USE_ASM_64IMPL 0
98 #if defined( VCL_VC ) && ( !defined( ITK_WRAPPING_PARSER ) ) && !defined( _WIN64 )
99 #define VC_USE_ASM_32IMPL 1
100 #define VC_USE_ASM_64IMPL 1
102 #define VC_USE_ASM_32IMPL 0
103 #define VC_USE_ASM_64IMPL 0
121 CLANG_SUPPRESS_Wfloat_equal
123 template<
typename TReturn,
typename TInput >
128 x +=
static_cast< TInput
>( 0.5 );
132 x -=
static_cast< TInput
>( 0.5 );
135 const TReturn r =
static_cast< TReturn
>( x );
136 return ( x != static_cast< TInput >( r ) ) ? r : static_cast< TReturn >( 2 * ( r / 2 ) );
139 template<
typename TReturn,
typename TInput >
142 x +=
static_cast< TInput
>( 0.5 );
143 const TReturn r =
static_cast< TReturn
>( x );
146 ( x == static_cast< TInput >( r ) ? r : r -
static_cast< TReturn
>( 1 ) );
149 template<
typename TReturn,
typename TInput >
152 const TReturn r =
static_cast< TReturn
>( x );
156 ( x == static_cast< TInput >( r ) ? r : r -
static_cast< TReturn
>( 1 ) );
159 template<
typename TReturn,
typename TInput >
162 const TReturn r =
static_cast< TReturn
>( x );
166 ( x == static_cast< TInput >( r ) ? r : r +
static_cast< TReturn
>( 1 ) );
174 #if USE_SSE2_32IMPL // sse2 implementation
178 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
179 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
181 return _mm_cvtsd_si32( _mm_set_sd(x) );
186 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
187 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
189 return _mm_cvtss_si32( _mm_set_ss(x) );
192 #elif GCC_USE_ASM_32IMPL // gcc asm implementation
196 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
197 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
200 __asm__ __volatile__ (
"fistpl %0" :
"=m" ( r ) :
"t" ( x ) :
"st" );
206 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
207 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
210 __asm__ __volatile__ (
"fistpl %0" :
"=m" ( r ) :
"t" ( x ) :
"st" );
214 #elif VC_USE_ASM_32IMPL // msvc asm implementation
218 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
219 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
232 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
233 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
244 #else // Base implementation
251 #if USE_SSE2_32IMPL || GCC_USE_ASM_32IMPL || VC_USE_ASM_32IMPL
262 #else // Base implementation
273 #endif // USE_SSE2_32IMPL || GCC_USE_ASM_32IMPL || VC_USE_ASM_32IMPL
278 #if USE_SSE2_64IMPL // sse2 implementation
282 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
283 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
285 return _mm_cvtsd_si64( _mm_set_sd(x) );
290 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
291 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
293 return _mm_cvtss_si64( _mm_set_ss(x) );
296 #elif GCC_USE_ASM_64IMPL // gcc asm implementation
300 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
301 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
304 __asm__ __volatile__ (
"fistpll %0" :
"=m" ( r ) :
"t" ( x ) :
"st" );
310 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
311 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
314 __asm__ __volatile__ (
"fistpll %0" :
"=m" ( r ) :
"t" ( x ) :
"st" );
318 #elif VC_USE_ASM_64IMPL // msvc asm implementation
322 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
323 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
336 #if defined( ITK_CHECK_FPU_ROUNDING_MODE ) && defined( HAVE_FENV_H )
337 itkAssertInDebugAndIgnoreInReleaseMacro(fegetround() == FE_TONEAREST);
348 #else // Base implementation
355 #if USE_SSE2_64IMPL || GCC_USE_ASM_64IMPL || VC_USE_ASM_64IMPL
366 #else // Base implementation
377 #endif // USE_SSE2_64IMPL || GCC_USE_ASM_64IMPL || VC_USE_ASM_64IMPL
379 template <
typename T>
396 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)