/******************************************************************/ /* fpunitControl.cpp */ /* ----------------------- */ /* */ /* This file contains the following functions, which may help to */ /* increase the performance of your floating-point intensive */ /* programs. Note that functions documented in the comment */ /* have been tested under VisualStudio.NET 2003 and gcc 3.4.4 */ /* (under Cygwin) on a 32-bit version of Windows. The usage */ /* under 64-bit environments is not guaranteed to work. */ /* */ /* void UseSinglePrecisionCalculations( void ); */ /* * Switches the CPU's FP unit to use only single-precision */ /* calculation. (Using 'float' instead of 'double' only */ /* uses smaller variable to store the results, but still */ /* performs calculations with double precision, by default) */ /* */ /* void UseDoublePrecisionCalculations( void ); */ /* * Switches the CPU's FP unit to use double-precision */ /* for calculations. */ /* */ /* Chris Wyman (1/10/2007) */ /******************************************************************/ /* */ /* For more info: http://www.stereopsis.com/FPU.html */ /* and: http://www.geisswerks.com/ryan/FAQS/fpu.html */ /* */ /******************************************************************/ // We use some VisualStudio-specific controls to simplify coding // under Windows. #if defined(WIN32) #include #else // Masks for the floating point control word, these are used in // non-Windows versions of the code. #define __FPU_CW_PREC_MASK__ (0x0300) #define __FPU_CW_PREC_SINGLE__ (0x0000) #define __FPU_CW_PREC_DOUBLE__ (0x0200) #define __FPU_CW_PREC_EXTENDED__ (0x0300) #endif // Switch to single-precision floating point computations. void UseSinglePrecisionCalculations( void ) { #if defined(WIN32) _controlfp(_PC_24, MCW_PC); #else // Get a copy of the current FP state unsigned int control = 0; __asm__ __volatile__ ( "fnstcw %0" : "=m" (control) ); // Check if single precision is already enabled if (control & __FPU_CW_PREC_MASK__) { // Nope... Setup single precision mode. control &= ~__FPU_CW_PREC_MASK__; // Write the new state back out. __asm__ __volatile__ ("fldcw %0" : : "m" (control)); } #endif } // Switch to double-precision floating point computations. void UseDoublePrecisionCalculations( void ) { #if defined(WIN32) _controlfp(_PC_53, MCW_PC); #else // Get a copy of the current FP state unsigned int control = 0; __asm__ __volatile__ ( "fnstcw %0" : "=m" (control) ); // Check if double precision is already enabled if (!(control & __FPU_CW_PREC_DOUBLE__)) { // Nope... Setup double precision mode. control &= ~__FPU_CW_PREC_MASK__; // Clear out any the register's precision bits control |= __FPU_CW_PREC_DOUBLE__; // Or in the new (double) value. // Write the new state back out. __asm__ __volatile__ ("fldcw %0" : : "m" (control)); } #endif }