ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

float_cast.h
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU Lesser General Public License as published by
00006 ** the Free Software Foundation; either version 2.1 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU Lesser General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU Lesser General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 */
00018 
00019 /* Version 1.5 */
00020 
00021 #ifndef FLOAT_CAST_HEADER
00022 #define FLOAT_CAST_HEADER
00023 
00024 /*============================================================================
00025 **  On Intel Pentium processors (especially PIII and probably P4), converting
00026 **  from float to int is very slow. To meet the C specs, the code produced by
00027 **  most C compilers targeting Pentium needs to change the FPU rounding mode
00028 **  before the float to int conversion is performed.
00029 **
00030 **  Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
00031 **  is this flushing of the pipeline which is so slow.
00032 **
00033 **  Fortunately the ISO C99 specifications define the functions lrint, lrintf,
00034 **  llrint and llrintf which fix this problem as a side effect.
00035 **
00036 **  On Unix-like systems, the configure process should have detected the
00037 **  presence of these functions. If they weren't found we have to replace them
00038 **  here with a standard C cast.
00039 */
00040 
00041 /*
00042 **  The C99 prototypes for lrint and lrintf are as follows:
00043 **
00044 **      long int lrintf (float x) ;
00045 **      long int lrint  (double x) ;
00046 */
00047 
00048 #include "config.h"
00049 
00050 /*
00051 **  The presence of the required functions are detected during the configure
00052 **  process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
00053 **  the config.h file.
00054 */
00055 
00056 #define     HAVE_LRINT_REPLACEMENT  0
00057 
00058 #if (HAVE_LRINT && HAVE_LRINTF)
00059 
00060     /*
00061     **  These defines enable functionality introduced with the 1999 ISO C
00062     **  standard. They must be defined before the inclusion of math.h to
00063     **  engage them. If optimisation is enabled, these functions will be
00064     **  inlined. With optimisation switched off, you have to link in the
00065     **  maths library using -lm.
00066     */
00067 
00068     #define _ISOC9X_SOURCE  1
00069     #define _ISOC99_SOURCE  1
00070 
00071     #define __USE_ISOC9X    1
00072     #define __USE_ISOC99    1
00073 
00074     #include    <math.h>
00075 
00076 #elif (defined (__CYGWIN__))
00077 
00078     #include    <math.h>
00079 
00080     #undef      HAVE_LRINT_REPLACEMENT
00081     #define     HAVE_LRINT_REPLACEMENT  1
00082 
00083     #undef  lrint
00084     #undef  lrintf
00085 
00086     #define lrint   double2int
00087     #define lrintf  float2int
00088 
00089     /*
00090     **  The native CYGWIN lrint and lrintf functions are buggy:
00091     **      http://sourceware.org/ml/cygwin/2005-06/msg00153.html
00092     **      http://sourceware.org/ml/cygwin/2005-09/msg00047.html
00093     **  and slow.
00094     **  These functions (pulled from the Public Domain MinGW math.h header)
00095     **  replace the native versions.
00096     */
00097 
00098     static inline long double2int (double in)
00099     {   long retval ;
00100 
00101         __asm__ __volatile__
00102         (   "fistpl %0"
00103             : "=m" (retval)
00104             : "t" (in)
00105             : "st"
00106             ) ;
00107 
00108         return retval ;
00109     } /* double2int */
00110 
00111     static inline long float2int (float in)
00112     {   long retval ;
00113 
00114         __asm__ __volatile__
00115         (   "fistpl %0"
00116             : "=m" (retval)
00117             : "t" (in)
00118             : "st"
00119             ) ;
00120 
00121         return retval ;
00122     } /* float2int */
00123 
00124 #elif (defined (WIN64) || defined(_WIN64))
00125 
00126     /*  Win64 section should be places before Win32 one, because
00127     **  most likely both WIN32 and WIN64 will be defined in 64-bit case.
00128     */
00129 
00130     #include    <math.h>
00131 
00132     /*  Win64 doesn't seem to have these functions, nor inline assembly.
00133     **  Therefore implement inline versions of these functions here.
00134     */
00135     #include    <emmintrin.h>
00136     #include    <mmintrin.h>
00137 
00138     __inline long int
00139     lrint(double flt)
00140     {
00141         return _mm_cvtsd_si32(_mm_load_sd(&flt));
00142     }
00143 
00144     __inline long int
00145     lrintf(float flt)
00146     {
00147         return _mm_cvtss_si32(_mm_load_ss(&flt));
00148     }
00149 
00150 #elif (defined (WIN32) || defined (_WIN32))
00151 
00152     #undef      HAVE_LRINT_REPLACEMENT
00153     #define     HAVE_LRINT_REPLACEMENT  1
00154 
00155     #include    <math.h>
00156 
00157     /*
00158     **  Win32 doesn't seem to have these functions.
00159     **  Therefore implement inline versions of these functions here.
00160     */
00161 
00162 #ifdef _MSC_VER
00163     __inline long int
00164     lrint (double flt)
00165     {   int intgr ;
00166 
00167         _asm
00168         {   fld flt
00169             fistp intgr
00170             } ;
00171 
00172         return intgr ;
00173     }
00174 
00175     __inline long int
00176     lrintf (float flt)
00177     {   int intgr ;
00178 
00179         _asm
00180         {   fld flt
00181             fistp intgr
00182             } ;
00183 
00184         return intgr ;
00185     }
00186 #else
00187     static __inline long int
00188     lrint (double flt)
00189     {
00190         int intgr ;
00191         __asm__ __volatile__ ("fldl %1; fistpl %0;" : "=m" (intgr) : "m" (flt));
00192         return intgr ;
00193     }
00194 
00195     static __inline long int
00196     lrintf (float flt)
00197     {
00198         int intgr ;
00199 
00200         __asm__ __volatile__ ("flds %1; fistpl %0;" : "=m" (intgr) : "m" (flt));
00201         return intgr ;
00202     }
00203 #endif
00204 
00205 #elif (defined (__MWERKS__) && defined (macintosh))
00206 
00207     /* This MacOS 9 solution was provided by Stephane Letz */
00208 
00209     #undef      HAVE_LRINT_REPLACEMENT
00210     #define     HAVE_LRINT_REPLACEMENT  1
00211     #include    <math.h>
00212 
00213     #undef  lrint
00214     #undef  lrintf
00215 
00216     #define lrint   double2int
00217     #define lrintf  float2int
00218 
00219     inline int
00220     float2int (register float in)
00221     {   long res [2] ;
00222 
00223         asm
00224         {   fctiw   in, in
00225             stfd     in, res
00226         }
00227         return res [1] ;
00228     } /* float2int */
00229 
00230     inline int
00231     double2int (register double in)
00232     {   long res [2] ;
00233 
00234         asm
00235         {   fctiw   in, in
00236             stfd     in, res
00237         }
00238         return res [1] ;
00239     } /* double2int */
00240 
00241 #elif (defined (__MACH__) && defined (__APPLE__))
00242 
00243     /* For Apple MacOSX. */
00244 
00245     #undef      HAVE_LRINT_REPLACEMENT
00246     #define     HAVE_LRINT_REPLACEMENT  1
00247     #include    <math.h>
00248 
00249     #undef lrint
00250     #undef lrintf
00251 
00252     #define lrint   double2int
00253     #define lrintf  float2int
00254 
00255     inline static long
00256     float2int (register float in)
00257     {   int res [2] ;
00258 
00259         __asm__ __volatile__
00260         (   "fctiw  %1, %1\n\t"
00261             "stfd   %1, %0"
00262             : "=m" (res)    /* Output */
00263             : "f" (in)      /* Input */
00264             : "memory"
00265             ) ;
00266 
00267         return res [1] ;
00268     } /* lrintf */
00269 
00270     inline static long
00271     double2int (register double in)
00272     {   int res [2] ;
00273 
00274         __asm__ __volatile__
00275         (   "fctiw  %1, %1\n\t"
00276             "stfd   %1, %0"
00277             : "=m" (res)    /* Output */
00278             : "f" (in)      /* Input */
00279             : "memory"
00280             ) ;
00281 
00282         return res [1] ;
00283     } /* lrint */
00284 
00285 #else
00286     #ifndef __sgi
00287     #warning "Don't have the functions lrint() and lrintf()."
00288     #warning "Replacing these functions with a standard C cast."
00289     #endif
00290 
00291     #include    <math.h>
00292 
00293     #define lrint(dbl)      ((long) (dbl))
00294     #define lrintf(flt)     ((long) (flt))
00295 
00296 #endif
00297 
00298 
00299 #endif /* FLOAT_CAST_HEADER */
00300 

Generated on Sun May 27 2012 04:34:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.