10 #include <vxl_config.h> 11 #include <vil/vil_config.h> 12 #ifdef VNL_CHECK_FPU_ROUNDING_MODE 13 # include <vcl_cassert.h> 17 #if VIL_CONFIG_ENABLE_SSE2_ROUNDING 18 # if !VXL_HAS_EMMINTRIN_H 19 # error "Required file emmintrin.h for SSE2 not found" 21 # include <emmintrin.h> 26 #if defined(__GNUC__) && ((defined(__i386__) || defined(__i386) || defined(__x86_64__) || defined(__x86_64))) 27 # define GCC_USE_FAST_IMPL 1 29 # define GCC_USE_FAST_IMPL 0 32 #if defined(_MSC_VER) && !defined(_WIN64) 33 # define VC_USE_FAST_IMPL 1 35 # define VC_USE_FAST_IMPL 0 51 #if VIL_CONFIG_ENABLE_SSE2_ROUNDING // Fast sse2 implementation 55 # if defined(VIL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 56 assert(fegetround()==FE_TONEAREST);
58 return _mm_cvtss_si32(_mm_set_ss(x));
62 # if defined(VIL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 63 assert(fegetround()==FE_TONEAREST);
65 return _mm_cvtsd_si32(_mm_set_sd(x));
68 #elif GCC_USE_FAST_IMPL // Fast gcc asm implementation 72 # ifdef VIL_CHECK_FPU_ROUNDING_MODE 73 assert(fegetround()==FE_TONEAREST);
76 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
81 # ifdef VIL_CHECK_FPU_ROUNDING_MODE 82 assert(fegetround()==FE_TONEAREST);
85 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
89 #elif VC_USE_FAST_IMPL // Fast msvc asm implementation 110 #else // Vanilla implementation 117 const int r = static_cast<int>(x);
118 if ( x != static_cast<float>(r) )
return r;
124 const int r = static_cast<int>(x);
125 if ( x != static_cast<float>(r) )
return r;
134 const int r = static_cast<int>(x);
135 if ( x != static_cast<double>(r) )
return r;
141 const int r = static_cast<int>(x);
142 if ( x != static_cast<double>(r) )
return r;
162 #if VIL_CONFIG_ENABLE_SSE2_ROUNDING || GCC_USE_FAST_IMPL || VC_USE_FAST_IMPL 167 #else // Vanilla implementation 172 return static_cast<int>(x>=0.f?x:(x==static_cast<int>(x)?x:x-1.f));
177 return static_cast<int>(x>=0.?x:(x==static_cast<int>(x)?x:x-1.));
195 #if VIL_CONFIG_ENABLE_SSE2_ROUNDING || GCC_USE_FAST_IMPL || VC_USE_FAST_IMPL 200 #else // Vanilla implementation 202 inline int vil_round_rnd(
float x) {
return x>=0.f?static_cast<int>(x+.5f):static_cast<int>(x-.5f); }
203 inline int vil_round_rnd(
double x) {
return x>=0.0?static_cast<int>(x+0.5):static_cast<int>(x-0.5); }
217 #if VIL_CONFIG_ENABLE_SSE2_ROUNDING // Fast sse2 implementation 221 # if defined(VIL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 222 assert(fegetround()==FE_TONEAREST);
224 return _mm_cvtss_si32(_mm_set_ss(2*x-.5f))>>1;
228 # if defined(VIL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 229 assert(fegetround()==FE_TONEAREST);
231 return _mm_cvtsd_si32(_mm_set_sd(2*x-.5))>>1;
234 #elif GCC_USE_FAST_IMPL // Fast gcc asm implementation 238 # ifdef VIL_CHECK_FPU_ROUNDING_MODE 239 assert(fegetround()==FE_TONEAREST);
243 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
248 # ifdef VIL_CHECK_FPU_ROUNDING_MODE 249 assert(fegetround()==FE_TONEAREST);
253 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
257 #elif VC_USE_FAST_IMPL // Fast msvc asm implementation 280 #else // Vanilla implementation 284 return static_cast<int>(x>=0.f?x:(x==static_cast<int>(x)?x:x-1.f));
288 return static_cast<int>(x>=0.0?x:(x==static_cast<int>(x)?x:x-1.0));
302 #if VIL_CONFIG_ENABLE_SSE2_ROUNDING // Fast sse2 implementation 306 # if defined(VIL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 307 assert(fegetround()==FE_TONEAREST);
309 return -(_mm_cvtss_si32(_mm_set_ss(-.5f-2*x))>>1);
313 # if defined(VIL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 314 assert(fegetround()==FE_TONEAREST);
316 return -(_mm_cvtsd_si32(_mm_set_sd(-.5-2*x))>>1);
319 #elif GCC_USE_FAST_IMPL // Fast gcc asm implementation 323 # ifdef VIL_CHECK_FPU_ROUNDING_MODE 324 assert(fegetround()==FE_TONEAREST);
328 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
333 # ifdef VIL_CHECK_FPU_ROUNDING_MODE 334 assert(fegetround()==FE_TONEAREST);
338 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
342 #elif VC_USE_FAST_IMPL // Fast msvc asm implementation 365 #else // Vanilla implementation 369 return static_cast<int>(x<0.f?x:(x==static_cast<int>(x)?x:x+1.f));
373 return static_cast<int>(x<0.0?x:(x==static_cast<int>(x)?x:x+1.0));
379 #endif // vil_round_h_ int vil_round_floor(float x)
int vil_round_rnd_halfintup(float x)
int vil_round_ceil(float x)
int vil_round_rnd_halfinttoeven(float x)
int vil_round_rnd(float x)