~ubuntu-branches/ubuntu/gutsy/audacity/gutsy-backports

« back to all changes in this revision

Viewing changes to lib-src/libsndfile/src/float_cast.h

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-18 21:58:19 UTC
  • mfrom: (13.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080218215819-tmbcf1rx238r8gdv
Tags: 1.3.4-1.1ubuntu1~gutsy1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
** Copyright (C) 2001-2004 Erik de Castro Lopo <erikd@mega-nerd.com>
3
 
**
4
 
** This program is free software; you can redistribute it and/or modify
5
 
** it under the terms of the GNU Lesser General Public License as published by
6
 
** the Free Software Foundation; either version 2.1 of the License, or
7
 
** (at your option) any later version.
8
 
**
9
 
** This program is distributed in the hope that it will be useful,
10
 
** but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
** GNU Lesser General Public License for more details.
13
 
**
14
 
** You should have received a copy of the GNU Lesser General Public License
15
 
** along with this program; if not, write to the Free Software
16
 
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
 
*/
18
 
 
19
 
/* Version 1.4 */
20
 
 
21
 
#ifndef FLOAT_CAST_HEADER
22
 
#define FLOAT_CAST_HEADER
23
 
 
24
 
/*============================================================================
25
 
**      On Intel Pentium processors (especially PIII and probably P4), converting
26
 
**      from float to int is very slow. To meet the C specs, the code produced by
27
 
**      most C compilers targeting Pentium needs to change the FPU rounding mode
28
 
**      before the float to int conversion is performed.
29
 
**
30
 
**      Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
31
 
**      is this flushing of the pipeline which is so slow.
32
 
**
33
 
**      Fortunately the ISO C99 specifications define the functions lrint, lrintf,
34
 
**      llrint and llrintf which fix this problem as a side effect.
35
 
**
36
 
**      On Unix-like systems, the configure process should have detected the
37
 
**      presence of these functions. If they weren't found we have to replace them
38
 
**      here with a standard C cast.
39
 
*/
40
 
 
41
 
/*
42
 
**      The C99 prototypes for lrint and lrintf are as follows:
43
 
**
44
 
**              long int lrintf (float x) ;
45
 
**              long int lrint  (double x) ;
46
 
*/
47
 
 
48
 
#include "sfconfig.h"
49
 
 
50
 
/*
51
 
**      The presence of the required functions are detected during the configure
52
 
**      process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
53
 
**      the sfconfig.h file.
54
 
*/
55
 
 
56
 
#define         HAVE_LRINT_REPLACEMENT  0
57
 
 
58
 
#if (HAVE_LRINT && HAVE_LRINTF)
59
 
 
60
 
        /*
61
 
        **      These defines enable functionality introduced with the 1999 ISO C
62
 
        **      standard. They must be defined before the inclusion of math.h to
63
 
        **      engage them. If optimisation is enabled, these functions will be
64
 
        **      inlined. With optimisation switched off, you have to link in the
65
 
        **      maths library using -lm.
66
 
        */
67
 
 
68
 
        #define _ISOC9X_SOURCE  1
69
 
        #define _ISOC99_SOURCE  1
70
 
 
71
 
        #define __USE_ISOC9X    1
72
 
        #define __USE_ISOC99    1
73
 
 
74
 
        #include        <math.h>
75
 
 
76
 
#elif (defined (__CYGWIN__))
77
 
 
78
 
        #include        <math.h>
79
 
 
80
 
        #undef          HAVE_LRINT_REPLACEMENT
81
 
        #define         HAVE_LRINT_REPLACEMENT  1
82
 
 
83
 
        #undef  lrint
84
 
        #undef  lrintf
85
 
 
86
 
        #define lrint   double2int
87
 
        #define lrintf  float2int
88
 
 
89
 
        /*
90
 
        **      The native CYGWIN lrint and lrintf functions are buggy:
91
 
        **              http://sourceware.org/ml/cygwin/2005-06/msg00153.html
92
 
        **              http://sourceware.org/ml/cygwin/2005-09/msg00047.html
93
 
        **      and slow.
94
 
        **      These functions (pulled from the Public Domain MinGW math.h header)
95
 
        **      replace the native versions.
96
 
        */
97
 
 
98
 
        static inline long double2int (double in)
99
 
        {       long retval ;
100
 
 
101
 
                __asm__ __volatile__
102
 
                (       "fistpl %0"
103
 
                        : "=m" (retval)
104
 
                        : "t" (in)
105
 
                        : "st"
106
 
                        ) ;
107
 
 
108
 
                return retval ;
109
 
        } /* double2int */
110
 
 
111
 
        static inline long float2int (float in)
112
 
        {       long retval ;
113
 
 
114
 
                __asm__ __volatile__
115
 
                (       "fistpl %0"
116
 
                        : "=m" (retval)
117
 
                        : "t" (in)
118
 
                        : "st"
119
 
                        ) ;
120
 
 
121
 
                return retval ;
122
 
        } /* float2int */
123
 
 
124
 
#elif (defined (WIN32) || defined (_WIN32))
125
 
 
126
 
        #undef          HAVE_LRINT_REPLACEMENT
127
 
        #define         HAVE_LRINT_REPLACEMENT  1
128
 
 
129
 
        #include        <math.h>
130
 
 
131
 
        /*
132
 
        **      Win32 doesn't seem to have these functions.
133
 
        **      Therefore implement inline versions of these functions here.
134
 
        */
135
 
 
136
 
        __inline long int
137
 
        lrint (double flt)
138
 
        {       int intgr ;
139
 
 
140
 
                _asm
141
 
                {       fld flt
142
 
                        fistp intgr
143
 
                        } ;
144
 
 
145
 
                return intgr ;
146
 
        }
147
 
 
148
 
        __inline long int
149
 
        lrintf (float flt)
150
 
        {       int intgr ;
151
 
 
152
 
                _asm
153
 
                {       fld flt
154
 
                        fistp intgr
155
 
                        } ;
156
 
 
157
 
                return intgr ;
158
 
        }
159
 
 
160
 
#elif (defined (__MWERKS__) && defined (macintosh))
161
 
 
162
 
        /* This MacOS 9 solution was provided by Stephane Letz */
163
 
 
164
 
        #undef          HAVE_LRINT_REPLACEMENT
165
 
        #define         HAVE_LRINT_REPLACEMENT  1
166
 
        #include        <math.h>
167
 
 
168
 
        #undef  lrint
169
 
        #undef  lrintf
170
 
 
171
 
        #define lrint   double2int
172
 
        #define lrintf  float2int
173
 
 
174
 
        inline int
175
 
        float2int (register float in)
176
 
        {       long res [2] ;
177
 
 
178
 
                asm
179
 
                {       fctiw   in, in
180
 
                        stfd     in, res
181
 
                }
182
 
                return res [1] ;
183
 
        } /* float2int */
184
 
 
185
 
        inline int
186
 
        double2int (register double in)
187
 
        {       long res [2] ;
188
 
 
189
 
                asm
190
 
                {       fctiw   in, in
191
 
                        stfd     in, res
192
 
                }
193
 
                return res [1] ;
194
 
        } /* double2int */
195
 
 
196
 
#elif (defined (__MACH__) && defined (__APPLE__))
197
 
 
198
 
        /* For Apple MacOSX. */
199
 
 
200
 
        #undef          HAVE_LRINT_REPLACEMENT
201
 
        #define         HAVE_LRINT_REPLACEMENT  1
202
 
        #include        <math.h>
203
 
 
204
 
        #undef lrint
205
 
        #undef lrintf
206
 
 
207
 
        #define lrint   double2int
208
 
        #define lrintf  float2int
209
 
 
210
 
        inline static long
211
 
        float2int (register float in)
212
 
        {       int res [2] ;
213
 
 
214
 
                __asm__ __volatile__
215
 
                (       "fctiw  %1, %1\n\t"
216
 
                        "stfd   %1, %0"
217
 
                        : "=m" (res)    /* Output */
218
 
                        : "f" (in)              /* Input */
219
 
                        : "memory"
220
 
                        ) ;
221
 
 
222
 
                return res [1] ;
223
 
        } /* lrintf */
224
 
 
225
 
        inline static long
226
 
        double2int (register double in)
227
 
        {       int res [2] ;
228
 
 
229
 
                __asm__ __volatile__
230
 
                (       "fctiw  %1, %1\n\t"
231
 
                        "stfd   %1, %0"
232
 
                        : "=m" (res)    /* Output */
233
 
                        : "f" (in)              /* Input */
234
 
                        : "memory"
235
 
                        ) ;
236
 
 
237
 
                return res [1] ;
238
 
        } /* lrint */
239
 
 
240
 
#else
241
 
        #ifndef __sgi
242
 
        #warning "Don't have the functions lrint() and lrintf()."
243
 
        #warning "Replacing these functions with a standard C cast."
244
 
        #endif
245
 
 
246
 
        #include        <math.h>
247
 
 
248
 
        #define lrint(dbl)              ((long) (dbl))
249
 
        #define lrintf(flt)             ((long) (flt))
250
 
 
251
 
#endif
252
 
 
253
 
 
254
 
#endif /* FLOAT_CAST_HEADER */
255
 
 
256
 
/*
257
 
** Do not edit or modify anything in this comment block.
258
 
** The arch-tag line is a file identity tag for the GNU Arch
259
 
** revision control system.
260
 
**
261
 
** arch-tag: 42db1693-ff61-4051-bac1-e4d24c4e30b7
262
 
*/