ieeefp.h (175178) | ieeefp.h (175179) |
---|---|
1/*- 2 * Copyright (c) 2003 Peter Wemm. 3 * Copyright (c) 1990 Andrew Moore, Talke Studio 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * from: @(#) ieeefp.h 1.0 (Berkeley) 9/23/93 | 1/*- 2 * Copyright (c) 2003 Peter Wemm. 3 * Copyright (c) 1990 Andrew Moore, Talke Studio 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 18 unchanged lines hidden (view full) --- 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * from: @(#) ieeefp.h 1.0 (Berkeley) 9/23/93 |
35 * $FreeBSD: head/sys/amd64/include/ieeefp.h 175178 2008-01-09 10:42:47Z bde $ | 35 * $FreeBSD: head/sys/amd64/include/ieeefp.h 175179 2008-01-09 13:35:31Z bde $ |
36 */ 37 38#ifndef _MACHINE_IEEEFP_H_ 39#define _MACHINE_IEEEFP_H_ 40 41/* 42 * IEEE floating point type, constant and function definitions. 43 */ --- 72 unchanged lines hidden (view full) --- 116 * SSE mxcsr register bit field offsets 117 */ 118#define SSE_STKY_OFF 0 /* exception flags offset */ 119#define SSE_DAZ_OFF 6 /* DAZ exception mask offset */ 120#define SSE_MSKS_OFF 7 /* other exception masks offset */ 121#define SSE_RND_OFF 13 /* rounding control offset */ 122#define SSE_FZ_OFF 15 /* flush to zero offset */ 123 | 36 */ 37 38#ifndef _MACHINE_IEEEFP_H_ 39#define _MACHINE_IEEEFP_H_ 40 41/* 42 * IEEE floating point type, constant and function definitions. 43 */ --- 72 unchanged lines hidden (view full) --- 116 * SSE mxcsr register bit field offsets 117 */ 118#define SSE_STKY_OFF 0 /* exception flags offset */ 119#define SSE_DAZ_OFF 6 /* DAZ exception mask offset */ 120#define SSE_MSKS_OFF 7 /* other exception masks offset */ 121#define SSE_RND_OFF 13 /* rounding control offset */ 122#define SSE_FZ_OFF 15 /* flush to zero offset */ 123 |
124#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE__) \ | 124#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) \ |
125 && !defined(__cplusplus) 126 | 125 && !defined(__cplusplus) 126 |
127#define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) 128#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) | |
129#define __fldcw(addr) __asm __volatile("fldcw %0" : : "m" (*(addr))) | 127#define __fldcw(addr) __asm __volatile("fldcw %0" : : "m" (*(addr))) |
128#define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) |
|
130#define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) | 129#define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) |
130#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) |
|
131#define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) 132#define __ldmxcsr(addr) __asm __volatile("ldmxcsr %0" : : "m" (*(addr))) 133#define __stmxcsr(addr) __asm __volatile("stmxcsr %0" : "=m" (*(addr))) 134 135/* 136 * General notes about conflicting SSE vs FP status bits. 137 * This code assumes that software will not fiddle with the control 138 * bits of the SSE and x87 in such a way to get them out of sync and 139 * still expect this to work. Break this at your peril. 140 * Because I based this on the i386 port, the x87 state is used for 141 * the fpget*() functions, and is shadowed into the SSE state for 142 * the fpset*() functions. For dual source fpget*() functions, I 143 * merge the two together. I think. 144 */ 145 | 131#define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) 132#define __ldmxcsr(addr) __asm __volatile("ldmxcsr %0" : : "m" (*(addr))) 133#define __stmxcsr(addr) __asm __volatile("stmxcsr %0" : "=m" (*(addr))) 134 135/* 136 * General notes about conflicting SSE vs FP status bits. 137 * This code assumes that software will not fiddle with the control 138 * bits of the SSE and x87 in such a way to get them out of sync and 139 * still expect this to work. Break this at your peril. 140 * Because I based this on the i386 port, the x87 state is used for 141 * the fpget*() functions, and is shadowed into the SSE state for 142 * the fpset*() functions. For dual source fpget*() functions, I 143 * merge the two together. I think. 144 */ 145 |
146static __inline__ fp_rnd_t | 146static __inline fp_rnd_t |
147__fpgetround(void) 148{ 149 unsigned short _cw; 150 151 __fnstcw(&_cw); 152 return ((_cw & FP_RND_FLD) >> FP_RND_OFF); 153} 154 | 147__fpgetround(void) 148{ 149 unsigned short _cw; 150 151 __fnstcw(&_cw); 152 return ((_cw & FP_RND_FLD) >> FP_RND_OFF); 153} 154 |
155static __inline__ fp_rnd_t | 155static __inline fp_rnd_t |
156__fpsetround(fp_rnd_t _m) 157{ 158 unsigned short _cw; | 156__fpsetround(fp_rnd_t _m) 157{ 158 unsigned short _cw; |
159 unsigned int _mxcsr; | 159 unsigned _mxcsr; |
160 fp_rnd_t _p; 161 162 __fnstcw(&_cw); 163 _p = (_cw & FP_RND_FLD) >> FP_RND_OFF; 164 _cw &= ~FP_RND_FLD; 165 _cw |= (_m << FP_RND_OFF) & FP_RND_FLD; 166 __fldcw(&_cw); 167 __stmxcsr(&_mxcsr); 168 _mxcsr &= ~SSE_RND_FLD; 169 _mxcsr |= (_m << SSE_RND_OFF) & SSE_RND_FLD; 170 __ldmxcsr(&_mxcsr); 171 return (_p); 172} 173 174/* 175 * Get or set the rounding precision for x87 arithmetic operations. 176 * There is no equivalent SSE mode or control. 177 */ 178 | 160 fp_rnd_t _p; 161 162 __fnstcw(&_cw); 163 _p = (_cw & FP_RND_FLD) >> FP_RND_OFF; 164 _cw &= ~FP_RND_FLD; 165 _cw |= (_m << FP_RND_OFF) & FP_RND_FLD; 166 __fldcw(&_cw); 167 __stmxcsr(&_mxcsr); 168 _mxcsr &= ~SSE_RND_FLD; 169 _mxcsr |= (_m << SSE_RND_OFF) & SSE_RND_FLD; 170 __ldmxcsr(&_mxcsr); 171 return (_p); 172} 173 174/* 175 * Get or set the rounding precision for x87 arithmetic operations. 176 * There is no equivalent SSE mode or control. 177 */ 178 |
179static __inline__ fp_prec_t | 179static __inline fp_prec_t |
180__fpgetprec(void) 181{ 182 unsigned short _cw; 183 184 __fnstcw(&_cw); 185 return ((_cw & FP_PRC_FLD) >> FP_PRC_OFF); 186} 187 | 180__fpgetprec(void) 181{ 182 unsigned short _cw; 183 184 __fnstcw(&_cw); 185 return ((_cw & FP_PRC_FLD) >> FP_PRC_OFF); 186} 187 |
188static __inline__ fp_prec_t | 188static __inline fp_prec_t |
189__fpsetprec(fp_rnd_t _m) 190{ | 189__fpsetprec(fp_rnd_t _m) 190{ |
191 unsigned short _cw; | |
192 fp_prec_t _p; | 191 fp_prec_t _p; |
192 unsigned short _cw; |
|
193 194 __fnstcw(&_cw); 195 _p = (_cw & FP_PRC_FLD) >> FP_PRC_OFF; 196 _cw &= ~FP_PRC_FLD; 197 _cw |= (_m << FP_PRC_OFF) & FP_PRC_FLD; 198 __fldcw(&_cw); 199 return (_p); 200} 201 202/* 203 * Get or set the exception mask. 204 * Note that the x87 mask bits are inverted by the API -- a mask bit of 1 205 * means disable for x87 and SSE, but for fp*mask() it means enable. 206 */ 207 | 193 194 __fnstcw(&_cw); 195 _p = (_cw & FP_PRC_FLD) >> FP_PRC_OFF; 196 _cw &= ~FP_PRC_FLD; 197 _cw |= (_m << FP_PRC_OFF) & FP_PRC_FLD; 198 __fldcw(&_cw); 199 return (_p); 200} 201 202/* 203 * Get or set the exception mask. 204 * Note that the x87 mask bits are inverted by the API -- a mask bit of 1 205 * means disable for x87 and SSE, but for fp*mask() it means enable. 206 */ 207 |
208static __inline__ fp_except_t | 208static __inline fp_except_t |
209__fpgetmask(void) 210{ 211 unsigned short _cw; 212 213 __fnstcw(&_cw); | 209__fpgetmask(void) 210{ 211 unsigned short _cw; 212 213 __fnstcw(&_cw); |
214 return ((~_cw) & FP_MSKS_FLD); | 214 return ((~_cw & FP_MSKS_FLD) >> FP_MSKS_OFF); |
215} 216 | 215} 216 |
217static __inline__ fp_except_t | 217static __inline fp_except_t |
218__fpsetmask(fp_except_t _m) 219{ | 218__fpsetmask(fp_except_t _m) 219{ |
220 unsigned short _cw; 221 unsigned int _mxcsr; | |
222 fp_except_t _p; | 220 fp_except_t _p; |
221 unsigned _mxcsr; 222 unsigned short _cw; |
|
223 224 __fnstcw(&_cw); | 223 224 __fnstcw(&_cw); |
225 _p = (~_cw) & FP_MSKS_FLD; | 225 _p = (~_cw & FP_MSKS_FLD) >> FP_MSKS_OFF; |
226 _cw &= ~FP_MSKS_FLD; | 226 _cw &= ~FP_MSKS_FLD; |
227 _cw |= (~_m) & FP_MSKS_FLD; | 227 _cw |= (~_m >> FP_MSKS_OFF) & FP_MSKS_FLD; |
228 __fldcw(&_cw); 229 __stmxcsr(&_mxcsr); 230 /* XXX should we clear non-ieee SSE_DAZ_FLD and SSE_FZ_FLD ? */ 231 _mxcsr &= ~SSE_MSKS_FLD; | 228 __fldcw(&_cw); 229 __stmxcsr(&_mxcsr); 230 /* XXX should we clear non-ieee SSE_DAZ_FLD and SSE_FZ_FLD ? */ 231 _mxcsr &= ~SSE_MSKS_FLD; |
232 _mxcsr |= ((~_m) << SSE_MSKS_OFF) & SSE_MSKS_FLD; | 232 _mxcsr |= (~_m << SSE_MSKS_OFF) & SSE_MSKS_FLD; |
233 __ldmxcsr(&_mxcsr); 234 return (_p); 235} 236 | 233 __ldmxcsr(&_mxcsr); 234 return (_p); 235} 236 |
237static __inline__ fp_except_t | 237static __inline fp_except_t |
238__fpgetsticky(void) 239{ | 238__fpgetsticky(void) 239{ |
240 unsigned short _sw; 241 unsigned int _mxcsr; | |
242 fp_except_t _ex; | 240 fp_except_t _ex; |
241 unsigned _mxcsr; 242 unsigned short _sw; |
|
243 244 __fnstsw(&_sw); | 243 244 __fnstsw(&_sw); |
245 _ex = _sw & FP_STKY_FLD; | 245 _ex = (_sw & FP_STKY_FLD) >> FP_STKY_OFF; |
246 __stmxcsr(&_mxcsr); | 246 __stmxcsr(&_mxcsr); |
247 _ex |= _mxcsr & SSE_STKY_FLD; | 247 _ex |= (_mxcsr & SSE_STKY_FLD) >> SSE_STKY_OFF; |
248 return (_ex); 249} 250 | 248 return (_ex); 249} 250 |
251#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE__ && !__cplusplus */ | 251#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE && !__cplusplus */ |
252 | 252 |
253#if !defined(__IEEEFP_NOINLINES__) && !defined(__cplusplus) \ 254 && defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE__) | 253#if !defined(__IEEEFP_NOINLINES__) && !defined(__cplusplus) && \ 254 defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE) |
255 256#define fpgetround() __fpgetround() 257#define fpsetround(_m) __fpsetround(_m) 258#define fpgetprec() __fpgetprec() 259#define fpsetprec(_m) __fpsetprec(_m) 260#define fpgetmask() __fpgetmask() 261#define fpsetmask(_m) __fpsetmask(_m) 262#define fpgetsticky() __fpgetsticky() 263 264/* Suppress prototypes in the MI header. */ 265#define _IEEEFP_INLINED_ 1 266 | 255 256#define fpgetround() __fpgetround() 257#define fpsetround(_m) __fpsetround(_m) 258#define fpgetprec() __fpgetprec() 259#define fpsetprec(_m) __fpsetprec(_m) 260#define fpgetmask() __fpgetmask() 261#define fpsetmask(_m) __fpsetmask(_m) 262#define fpgetsticky() __fpgetsticky() 263 264/* Suppress prototypes in the MI header. */ 265#define _IEEEFP_INLINED_ 1 266 |
267#else /* !(!__IEEEFP_NOINLINES__ && !__cplusplus && __GNUCLIKE_ASM 268 && __CC_SUPPORTS___INLINE__) */ | 267#else /* !(!__IEEEFP_NOINLINES__ && !__cplusplus && __GNUCLIKE_ASM && 268 __CC_SUPPORTS___INLINE) */ |
269 270/* Augment the userland declarations. */ 271__BEGIN_DECLS | 269 270/* Augment the userland declarations. */ 271__BEGIN_DECLS |
272extern fp_prec_t fpgetprec(void); 273extern fp_prec_t fpsetprec(fp_prec_t); | 272fp_prec_t fpgetprec(void); 273fp_prec_t fpsetprec(fp_prec_t); |
274__END_DECLS 275 | 274__END_DECLS 275 |
276#endif /* !__IEEEFP_NOINLINES__ && !__cplusplus && __GNUCLIKE_ASM 277 && __CC_SUPPORTS___INLINE__ */ | 276#endif /* !__IEEEFP_NOINLINES__ && !__cplusplus && __GNUCLIKE_ASM && 277 __CC_SUPPORTS___INLINE */ |
278 279#endif /* !_MACHINE_IEEEFP_H_ */ | 278 279#endif /* !_MACHINE_IEEEFP_H_ */ |