[CRT] spawn: define a unicode environment when needed
[reactos.git] / sdk / lib / 3rdparty / libsamplerate / float_cast.h
1 /*
2 ** Copyright (c) 2001-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** All rights reserved.
4 **
5 ** This code is released under 2-clause BSD license. Please see the
6 ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
7 */
8
9 /* Version 1.5 */
10
11 #ifndef FLOAT_CAST_HEADER
12 #define FLOAT_CAST_HEADER
13
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.
19 **
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.
22 **
23 ** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
24 ** llrint and llrintf which fix this problem as a side effect.
25 **
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.
29 */
30
31 /*
32 ** The C99 prototypes for lrint and lrintf are as follows:
33 **
34 ** long int lrintf (float x) ;
35 ** long int lrint (double x) ;
36 */
37
38 #include "config.h"
39
40 /*
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
43 ** the config.h file.
44 */
45
46 #define HAVE_LRINT_REPLACEMENT 0
47
48 #if (HAVE_LRINT && HAVE_LRINTF)
49
50 /*
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.
56 */
57
58 #define _ISOC9X_SOURCE 1
59 #define _ISOC99_SOURCE 1
60
61 #define __USE_ISOC9X 1
62 #define __USE_ISOC99 1
63
64 #include <math.h>
65
66 #elif (defined (__CYGWIN__))
67
68 #include <math.h>
69
70 #undef HAVE_LRINT_REPLACEMENT
71 #define HAVE_LRINT_REPLACEMENT 1
72
73 #undef lrint
74 #undef lrintf
75
76 #define lrint double2int
77 #define lrintf float2int
78
79 /*
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
83 ** and slow.
84 ** These functions (pulled from the Public Domain MinGW math.h header)
85 ** replace the native versions.
86 */
87
88 static inline long double2int (double in)
89 { long retval ;
90
91 __asm__ __volatile__
92 ( "fistpl %0"
93 : "=m" (retval)
94 : "t" (in)
95 : "st"
96 ) ;
97
98 return retval ;
99 } /* double2int */
100
101 static inline long float2int (float in)
102 { long retval ;
103
104 __asm__ __volatile__
105 ( "fistpl %0"
106 : "=m" (retval)
107 : "t" (in)
108 : "st"
109 ) ;
110
111 return retval ;
112 } /* float2int */
113
114 #elif (defined (WIN64) || defined(_WIN64))
115
116 /* Win64 section should be places before Win32 one, because
117 ** most likely both WIN32 and WIN64 will be defined in 64-bit case.
118 */
119
120 #include <math.h>
121
122 /* Win64 doesn't seem to have these functions, nor inline assembly.
123 ** Therefore implement inline versions of these functions here.
124 */
125 #include <emmintrin.h>
126 #include <mmintrin.h>
127
128 __inline long int
129 lrint(double flt)
130 {
131 return _mm_cvtsd_si32(_mm_load_sd(&flt));
132 }
133
134 __inline long int
135 lrintf(float flt)
136 {
137 return _mm_cvtss_si32(_mm_load_ss(&flt));
138 }
139
140 #elif (defined (WIN32) || defined (_WIN32))
141
142 #undef HAVE_LRINT_REPLACEMENT
143 #define HAVE_LRINT_REPLACEMENT 1
144
145 #include <math.h>
146
147 /*
148 ** Win32 doesn't seem to have these functions.
149 ** Therefore implement inline versions of these functions here.
150 */
151
152 #ifdef _MSC_VER
153 __inline long int
154 lrint (double flt)
155 { int intgr ;
156
157 _asm
158 { fld flt
159 fistp intgr
160 } ;
161
162 return intgr ;
163 }
164
165 __inline long int
166 lrintf (float flt)
167 { int intgr ;
168
169 _asm
170 { fld flt
171 fistp intgr
172 } ;
173
174 return intgr ;
175 }
176 #endif
177
178 #elif (defined (__MWERKS__) && defined (macintosh))
179
180 /* This MacOS 9 solution was provided by Stephane Letz */
181
182 #undef HAVE_LRINT_REPLACEMENT
183 #define HAVE_LRINT_REPLACEMENT 1
184 #include <math.h>
185
186 #undef lrint
187 #undef lrintf
188
189 #define lrint double2int
190 #define lrintf float2int
191
192 inline int
193 float2int (register float in)
194 { long res [2] ;
195
196 asm
197 { fctiw in, in
198 stfd in, res
199 }
200 return res [1] ;
201 } /* float2int */
202
203 inline int
204 double2int (register double in)
205 { long res [2] ;
206
207 asm
208 { fctiw in, in
209 stfd in, res
210 }
211 return res [1] ;
212 } /* double2int */
213
214 #elif (defined (__MACH__) && defined (__APPLE__))
215
216 /* For Apple MacOSX. */
217
218 #undef HAVE_LRINT_REPLACEMENT
219 #define HAVE_LRINT_REPLACEMENT 1
220 #include <math.h>
221
222 #undef lrint
223 #undef lrintf
224
225 #define lrint double2int
226 #define lrintf float2int
227
228 inline static long
229 float2int (register float in)
230 { int res [2] ;
231
232 __asm__ __volatile__
233 ( "fctiw %1, %1\n\t"
234 "stfd %1, %0"
235 : "=m" (res) /* Output */
236 : "f" (in) /* Input */
237 : "memory"
238 ) ;
239
240 return res [1] ;
241 } /* lrintf */
242
243 inline static long
244 double2int (register double in)
245 { int res [2] ;
246
247 __asm__ __volatile__
248 ( "fctiw %1, %1\n\t"
249 "stfd %1, %0"
250 : "=m" (res) /* Output */
251 : "f" (in) /* Input */
252 : "memory"
253 ) ;
254
255 return res [1] ;
256 } /* lrint */
257
258 #else
259 #ifndef __sgi
260 #warning "Don't have the functions lrint() and lrintf()."
261 #warning "Replacing these functions with a standard C cast."
262 #endif
263
264 #include <math.h>
265
266 #define lrint(dbl) ((long) (dbl))
267 #define lrintf(flt) ((long) (flt))
268
269 #endif
270
271
272 #endif /* FLOAT_CAST_HEADER */
273