Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274/*** Copyright (c) 2001-2016, Erik de Castro Lopo <erikd@mega-nerd.com>** All rights reserved.**** This code is released under 2-clause BSD license. Please see the** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING*/
/* Version 1.5 */
#ifndef FLOAT_CAST_HEADER#define FLOAT_CAST_HEADER
/*============================================================================** On Intel Pentium processors (especially PIII and probably P4), converting** from float to int is very slow. To meet the C specs, the code produced by** most C compilers targeting Pentium needs to change the FPU rounding mode** before the float to int conversion is performed.**** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It** is this flushing of the pipeline which is so slow.**** Fortunately the ISO C99 specifications define the functions lrint, lrintf,** llrint and llrintf which fix this problem as a side effect.**** On Unix-like systems, the configure process should have detected the** presence of these functions. If they weren't found we have to replace them** here with a standard C cast.*/
/*** The C99 prototypes for lrint and lrintf are as follows:**** long int lrintf (float x) ;** long int lrint (double x) ;*/
#include "config.h"
/*** The presence of the required functions are detected during the configure** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in** the config.h file.*/
#define HAVE_LRINT_REPLACEMENT 0
#if (HAVE_LRINT && HAVE_LRINTF)
/* ** These defines enable functionality introduced with the 1999 ISO C ** standard. They must be defined before the inclusion of math.h to ** engage them. If optimisation is enabled, these functions will be ** inlined. With optimisation switched off, you have to link in the ** maths library using -lm. */
#define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1
#define __USE_ISOC9X 1 #define __USE_ISOC99 1
#include <math.h>
#elif (defined (__CYGWIN__))
#include <math.h>
#undef HAVE_LRINT_REPLACEMENT #define HAVE_LRINT_REPLACEMENT 1
#undef lrint #undef lrintf
#define lrint double2int #define lrintf float2int
/* ** The native CYGWIN lrint and lrintf functions are buggy: ** http://sourceware.org/ml/cygwin/2005-06/msg00153.html ** http://sourceware.org/ml/cygwin/2005-09/msg00047.html ** and slow. ** These functions (pulled from the Public Domain MinGW math.h header) ** replace the native versions. */
static inline long double2int (double in) { long retval ;
__asm__ __volatile__ ( "fistpl %0" : "=m" (retval) : "t" (in) : "st" ) ;
return retval ; } /* double2int */
static inline long float2int (float in) { long retval ;
__asm__ __volatile__ ( "fistpl %0" : "=m" (retval) : "t" (in) : "st" ) ;
return retval ; } /* float2int */
#elif (defined (WIN64) || defined(_WIN64))
/* Win64 section should be places before Win32 one, because ** most likely both WIN32 and WIN64 will be defined in 64-bit case. */
#include <math.h>
/* Win64 doesn't seem to have these functions, nor inline assembly. ** Therefore implement inline versions of these functions here. */ #include <emmintrin.h> #include <mmintrin.h>
__inline long int lrint(double flt) { return _mm_cvtsd_si32(_mm_load_sd(&flt)); }
__inline long int lrintf(float flt) { return _mm_cvtss_si32(_mm_load_ss(&flt)); }
#elif (defined (WIN32) || defined (_WIN32))
#undef HAVE_LRINT_REPLACEMENT #define HAVE_LRINT_REPLACEMENT 1
#include <math.h>
/* ** Win32 doesn't seem to have these functions. ** Therefore implement inline versions of these functions here. */
#ifdef _MSC_VER __inline long int lrint (double flt) { int intgr ;
_asm { fld flt fistp intgr } ;
return intgr ; }
__inline long int lrintf (float flt) { int intgr ;
_asm { fld flt fistp intgr } ;
return intgr ; }#endif
#elif (defined (__MWERKS__) && defined (macintosh))
/* This MacOS 9 solution was provided by Stephane Letz */
#undef HAVE_LRINT_REPLACEMENT #define HAVE_LRINT_REPLACEMENT 1 #include <math.h>
#undef lrint #undef lrintf
#define lrint double2int #define lrintf float2int
inline int float2int (register float in) { long res [2] ;
asm { fctiw in, in stfd in, res } return res [1] ; } /* float2int */
inline int double2int (register double in) { long res [2] ;
asm { fctiw in, in stfd in, res } return res [1] ; } /* double2int */
#elif (defined (__MACH__) && defined (__APPLE__))
/* For Apple MacOSX. */
#undef HAVE_LRINT_REPLACEMENT #define HAVE_LRINT_REPLACEMENT 1 #include <math.h>
#undef lrint #undef lrintf
#define lrint double2int #define lrintf float2int
inline static long float2int (register float in) { int res [2] ;
__asm__ __volatile__ ( "fctiw %1, %1\n\t" "stfd %1, %0" : "=m" (res) /* Output */ : "f" (in) /* Input */ : "memory" ) ;
return res [1] ; } /* lrintf */
inline static long double2int (register double in) { int res [2] ;
__asm__ __volatile__ ( "fctiw %1, %1\n\t" "stfd %1, %0" : "=m" (res) /* Output */ : "f" (in) /* Input */ : "memory" ) ;
return res [1] ; } /* lrint */
#else #ifndef __sgi #warning "Don't have the functions lrint() and lrintf()." #warning "Replacing these functions with a standard C cast." #endif
#include <math.h>
#define lrint(dbl) ((long) (dbl)) #define lrintf(flt) ((long) (flt))
#endif
#endif /* FLOAT_CAST_HEADER */