Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencntrlfp.c
Go to the documentation of this file.
00001 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ 00002 00003 #include <precomp.h> 00004 #include <float.h> 00005 00006 #define X87_CW_IM (1<<0) /* Invalid operation mask */ 00007 #define X87_CW_DM (1<<1) /* Denormal operand mask */ 00008 #define X87_CW_ZM (1<<2) /* Zero divide mask */ 00009 #define X87_CW_OM (1<<3) /* Overflow mask */ 00010 #define X87_CW_UM (1<<4) /* Underflow mask */ 00011 #define X87_CW_PM (1<<5) /* Precision mask */ 00012 00013 #define X87_CW_PC_MASK (3<<8) /* precision control mask */ 00014 #define X87_CW_PC24 (0<<8) /* 24 bit precision */ 00015 #define X87_CW_PC53 (2<<8) /* 53 bit precision */ 00016 #define X87_CW_PC64 (3<<8) /* 64 bit precision */ 00017 00018 #define X87_CW_RC_MASK (3<<10) /* rounding control mask */ 00019 #define X87_CW_RC_NEAREST (0<<10) /* round to nearest */ 00020 #define X87_CW_RC_DOWN (1<<10) /* round down */ 00021 #define X87_CW_RC_UP (2<<10) /* round up */ 00022 #define X87_CW_RC_ZERO (3<<10) /* round toward zero (chop) */ 00023 00024 #define X87_CW_IC (1<<12) /* infinity control flag */ 00025 00026 #ifdef _M_AMD64 00027 unsigned int __getfpcw87(void); 00028 void __setfpcw87(unsigned int); 00029 #endif 00030 00031 /* 00032 * @implemented 00033 */ 00034 00035 unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask) 00036 { 00037 return _control87( newval, mask & ~_EM_DENORMAL ); 00038 } 00039 00040 /********************************************************************* 00041 * _control87 (MSVCRT.@) 00042 */ 00043 unsigned int CDECL _control87(unsigned int newval, unsigned int mask) 00044 { 00045 unsigned int fpword = 0; 00046 unsigned int flags = 0; 00047 00048 TRACE("(%08x, %08x): Called\n", newval, mask); 00049 00050 /* Get fp control word */ 00051 #ifdef _M_AMD64 00052 fpword = __getfpcw87(); 00053 #elif defined(__GNUC__) 00054 __asm__ __volatile__( "fstcw %0" : "=m" (fpword) : ); 00055 #else 00056 __asm fstcw [fpword]; 00057 #endif 00058 00059 TRACE("Control word before : %08x\n", fpword); 00060 00061 /* Convert into mask constants */ 00062 if (fpword & 0x1) flags |= _EM_INVALID; 00063 if (fpword & 0x2) flags |= _EM_DENORMAL; 00064 if (fpword & 0x4) flags |= _EM_ZERODIVIDE; 00065 if (fpword & 0x8) flags |= _EM_OVERFLOW; 00066 if (fpword & 0x10) flags |= _EM_UNDERFLOW; 00067 if (fpword & 0x20) flags |= _EM_INEXACT; 00068 switch(fpword & 0xC00) { 00069 case 0xC00: flags |= _RC_UP|_RC_DOWN; break; 00070 case 0x800: flags |= _RC_UP; break; 00071 case 0x400: flags |= _RC_DOWN; break; 00072 } 00073 switch(fpword & 0x300) { 00074 case 0x0: flags |= _PC_24; break; 00075 case 0x200: flags |= _PC_53; break; 00076 case 0x300: flags |= _PC_64; break; 00077 } 00078 if (fpword & 0x1000) flags |= _IC_AFFINE; 00079 00080 /* Mask with parameters */ 00081 flags = (flags & ~mask) | (newval & mask); 00082 00083 /* Convert (masked) value back to fp word */ 00084 fpword = 0; 00085 if (flags & _EM_INVALID) fpword |= 0x1; 00086 if (flags & _EM_DENORMAL) fpword |= 0x2; 00087 if (flags & _EM_ZERODIVIDE) fpword |= 0x4; 00088 if (flags & _EM_OVERFLOW) fpword |= 0x8; 00089 if (flags & _EM_UNDERFLOW) fpword |= 0x10; 00090 if (flags & _EM_INEXACT) fpword |= 0x20; 00091 switch(flags & (_RC_UP | _RC_DOWN)) { 00092 case _RC_UP|_RC_DOWN: fpword |= 0xC00; break; 00093 case _RC_UP: fpword |= 0x800; break; 00094 case _RC_DOWN: fpword |= 0x400; break; 00095 } 00096 switch (flags & (_PC_24 | _PC_53)) { 00097 case _PC_64: fpword |= 0x300; break; 00098 case _PC_53: fpword |= 0x200; break; 00099 case _PC_24: fpword |= 0x0; break; 00100 } 00101 if (flags & _IC_AFFINE) fpword |= 0x1000; 00102 00103 TRACE("Control word after : %08x\n", fpword); 00104 00105 /* Put fp control word */ 00106 #ifdef _M_AMD64 00107 __setfpcw87(fpword); 00108 #elif defined(__GNUC__) 00109 __asm__ __volatile__( "fldcw %0" : : "m" (fpword) ); 00110 #else 00111 __asm fldcw [fpword]; 00112 #endif 00113 00114 return flags; 00115 } 00116 00117 /********************************************************************* 00118 * _controlfp_s (MSVCRT.@) 00119 */ 00120 int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask) 00121 { 00122 #ifdef __i386__ 00123 unsigned int flags; 00124 00125 FIXME("(%p %u %u) semi-stub\n", cur, newval, mask); 00126 00127 flags = _control87( newval, mask & ~_EM_DENORMAL ); 00128 00129 if(cur) 00130 *cur = flags; 00131 00132 return 0; 00133 #else 00134 FIXME(":Not Implemented!\n"); 00135 return 0; 00136 #endif 00137 } Generated on Fri May 25 2012 04:34:54 for ReactOS by
1.7.6.1
|