2 ** Copyright (c) 2001-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** All rights reserved.
5 ** This code is released under 2-clause BSD license. Please see the
6 ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
11 #ifndef FLOAT_CAST_HEADER
12 #define FLOAT_CAST_HEADER
14 /*============================================================================
15 ** On Intel Pentium processors (especially PIII and probably P4), converting
16 ** from float to int is very slow. To meet the C specs, the code produced by
17 ** most C compilers targeting Pentium needs to change the FPU rounding mode
18 ** before the float to int conversion is performed.
20 ** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
21 ** is this flushing of the pipeline which is so slow.
23 ** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
24 ** llrint and llrintf which fix this problem as a side effect.
26 ** On Unix-like systems, the configure process should have detected the
27 ** presence of these functions. If they weren't found we have to replace them
28 ** here with a standard C cast.
32 ** The C99 prototypes for lrint and lrintf are as follows:
34 ** long int lrintf (float x) ;
35 ** long int lrint (double x) ;
41 ** The presence of the required functions are detected during the configure
42 ** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
46 #define HAVE_LRINT_REPLACEMENT 0
48 #if (HAVE_LRINT && HAVE_LRINTF)
51 ** These defines enable functionality introduced with the 1999 ISO C
52 ** standard. They must be defined before the inclusion of math.h to
53 ** engage them. If optimisation is enabled, these functions will be
54 ** inlined. With optimisation switched off, you have to link in the
55 ** maths library using -lm.
58 #define _ISOC9X_SOURCE 1
59 #define _ISOC99_SOURCE 1
61 #define __USE_ISOC9X 1
62 #define __USE_ISOC99 1
66 #elif (defined (__CYGWIN__))
70 #undef HAVE_LRINT_REPLACEMENT
71 #define HAVE_LRINT_REPLACEMENT 1
76 #define lrint double2int
77 #define lrintf float2int
80 ** The native CYGWIN lrint and lrintf functions are buggy:
81 ** http://sourceware.org/ml/cygwin/2005-06/msg00153.html
82 ** http://sourceware.org/ml/cygwin/2005-09/msg00047.html
84 ** These functions (pulled from the Public Domain MinGW math.h header)
85 ** replace the native versions.
88 static inline long double2int (double in
)
101 static inline long float2int (float in
)
114 #elif (defined (WIN64) || defined(_WIN64))
116 /* Win64 section should be places before Win32 one, because
117 ** most likely both WIN32 and WIN64 will be defined in 64-bit case.
122 /* Win64 doesn't seem to have these functions, nor inline assembly.
123 ** Therefore implement inline versions of these functions here.
125 #include <emmintrin.h>
126 #include <mmintrin.h>
131 return _mm_cvtsd_si32(_mm_load_sd(&flt
));
137 return _mm_cvtss_si32(_mm_load_ss(&flt
));
140 #elif (defined (WIN32) || defined (_WIN32))
142 #undef HAVE_LRINT_REPLACEMENT
143 #define HAVE_LRINT_REPLACEMENT 1
148 ** Win32 doesn't seem to have these functions.
149 ** Therefore implement inline versions of these functions here.
178 #elif (defined (__MWERKS__) && defined (macintosh))
180 /* This MacOS 9 solution was provided by Stephane Letz */
182 #undef HAVE_LRINT_REPLACEMENT
183 #define HAVE_LRINT_REPLACEMENT 1
189 #define lrint double2int
190 #define lrintf float2int
193 float2int (register float in
)
204 double2int (register double in
)
214 #elif (defined (__MACH__) && defined (__APPLE__))
216 /* For Apple MacOSX. */
218 #undef HAVE_LRINT_REPLACEMENT
219 #define HAVE_LRINT_REPLACEMENT 1
225 #define lrint double2int
226 #define lrintf float2int
229 float2int (register float in
)
235 : "=m" (res
) /* Output */
236 : "f" (in
) /* Input */
244 double2int (register double in
)
250 : "=m" (res
) /* Output */
251 : "f" (in
) /* Input */
260 #warning "Don't have the functions lrint() and lrintf()."
261 #warning "Replacing these functions with a standard C cast."
266 #define lrint(dbl) ((long) (dbl))
267 #define lrintf(flt) ((long) (flt))
272 #endif /* FLOAT_CAST_HEADER */