diff options
author | bde <bde@FreeBSD.org> | 1994-09-20 22:26:37 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1994-09-20 22:26:37 +0000 |
commit | a547491c3d664f958f17c58d4692e0465368adcc (patch) | |
tree | c8f752fd3cf3c1b7bd2dbacd60209a1802365022 | |
parent | 516108a214d464c523685f3be2bbc4169dee95d2 (diff) | |
download | FreeBSD-src-a547491c3d664f958f17c58d4692e0465368adcc.zip FreeBSD-src-a547491c3d664f958f17c58d4692e0465368adcc.tar.gz |
Don't provide bogus source operands in some asms. This probably shouldn't
matter, but similar bogusness in npx.c causes compiling without -O to fail.
Use __volatile in all asms.
Parenthesize macro args.
Change the names of the macros to avoid namespace pollution.
Remove unnecessary "#ifdef __i386__".
Sort #defines.
Add comments.
-rw-r--r-- | sys/amd64/include/floatingpoint.h | 46 | ||||
-rw-r--r-- | sys/i386/include/floatingpoint.h | 46 |
2 files changed, 58 insertions, 34 deletions
diff --git a/sys/amd64/include/floatingpoint.h b/sys/amd64/include/floatingpoint.h index 182e5a3..69cb204 100644 --- a/sys/amd64/include/floatingpoint.h +++ b/sys/amd64/include/floatingpoint.h @@ -31,28 +31,31 @@ * SUCH DAMAGE. * * from: @(#) floatingpoint.h 1.0 (Berkeley) 9/23/93 - * $Id: floatingpoint.h,v 1.4 1993/11/07 17:42:55 wollman Exp $ + * $Id: floatingpoint.h,v 1.5 1994/08/04 19:16:36 wollman Exp $ */ +#ifndef _FLOATINGPOINT_H_ +#define _FLOATINGPOINT_H_ + /* - * IEEE floating point structure and function definitions + * IEEE floating point structure and function definitions */ -#ifndef _FLOATINGPOINT_H_ -#define _FLOATINGPOINT_H_ +/*- + * XXX the following undocumented pollution is exported: + * fpsetsticky(). + * FP*FLD, FP*OFF and FP*REG from <machine/ieeefp.h> + */ #include <sys/cdefs.h> #include <machine/ieeefp.h> #ifdef __GNUC__ -#ifdef __i386__ - -#define fnstcw(addr) __asm("fnstcw %0" : "=m" (*addr) : "0" (*addr)) -#define fnstsw(addr) __asm("fnstsw %0" : "=m" (*addr) : "0" (*addr)) -#define fnstenv(addr) __asm("fnstenv %0" : "=m" (*addr) : "0" (*addr)) -#define fldenv(addr) __asm("fldenv %0" : : "m" (*addr)) - +#define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) +#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) +#define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) +#define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) /* * return the contents of a FP register @@ -62,12 +65,20 @@ __fpgetreg(int _reg) { unsigned short _mem; + /*- + * This is more efficient than it looks. The switch gets optimized + * away if _reg is constant. + * + * The default case only supports _reg == 0. We could handle more + * registers (e.g., tags) using fnstenv, but the interface doesn't + * support more. + */ switch(_reg) { default: - fnstcw(&_mem); + __fnstcw(&_mem); break; case FP_STKY_REG: - fnstsw(&_mem); + __fnstsw(&_mem); break; } return _mem; @@ -82,15 +93,16 @@ __fpsetreg(int _m, int _reg, int _fld, int _off) unsigned _env[7]; unsigned _p; - fnstenv(_env); + /* + * _reg == 0 could be handled better using fnstcw/fldcw. + */ + __fnstenv(_env); _p = (_env[_reg] & _fld) >> _off; _env[_reg] = (_env[_reg] & ~_fld) | (_m << _off & _fld); - fldenv(_env); + __fldenv(_env); return _p; } -#endif /* __i386__ */ - #endif /* __GNUC__ */ /* diff --git a/sys/i386/include/floatingpoint.h b/sys/i386/include/floatingpoint.h index 182e5a3..69cb204 100644 --- a/sys/i386/include/floatingpoint.h +++ b/sys/i386/include/floatingpoint.h @@ -31,28 +31,31 @@ * SUCH DAMAGE. * * from: @(#) floatingpoint.h 1.0 (Berkeley) 9/23/93 - * $Id: floatingpoint.h,v 1.4 1993/11/07 17:42:55 wollman Exp $ + * $Id: floatingpoint.h,v 1.5 1994/08/04 19:16:36 wollman Exp $ */ +#ifndef _FLOATINGPOINT_H_ +#define _FLOATINGPOINT_H_ + /* - * IEEE floating point structure and function definitions + * IEEE floating point structure and function definitions */ -#ifndef _FLOATINGPOINT_H_ -#define _FLOATINGPOINT_H_ +/*- + * XXX the following undocumented pollution is exported: + * fpsetsticky(). + * FP*FLD, FP*OFF and FP*REG from <machine/ieeefp.h> + */ #include <sys/cdefs.h> #include <machine/ieeefp.h> #ifdef __GNUC__ -#ifdef __i386__ - -#define fnstcw(addr) __asm("fnstcw %0" : "=m" (*addr) : "0" (*addr)) -#define fnstsw(addr) __asm("fnstsw %0" : "=m" (*addr) : "0" (*addr)) -#define fnstenv(addr) __asm("fnstenv %0" : "=m" (*addr) : "0" (*addr)) -#define fldenv(addr) __asm("fldenv %0" : : "m" (*addr)) - +#define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) +#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) +#define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) +#define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) /* * return the contents of a FP register @@ -62,12 +65,20 @@ __fpgetreg(int _reg) { unsigned short _mem; + /*- + * This is more efficient than it looks. The switch gets optimized + * away if _reg is constant. + * + * The default case only supports _reg == 0. We could handle more + * registers (e.g., tags) using fnstenv, but the interface doesn't + * support more. + */ switch(_reg) { default: - fnstcw(&_mem); + __fnstcw(&_mem); break; case FP_STKY_REG: - fnstsw(&_mem); + __fnstsw(&_mem); break; } return _mem; @@ -82,15 +93,16 @@ __fpsetreg(int _m, int _reg, int _fld, int _off) unsigned _env[7]; unsigned _p; - fnstenv(_env); + /* + * _reg == 0 could be handled better using fnstcw/fldcw. + */ + __fnstenv(_env); _p = (_env[_reg] & _fld) >> _off; _env[_reg] = (_env[_reg] & ~_fld) | (_m << _off & _fld); - fldenv(_env); + __fldenv(_env); return _p; } -#endif /* __i386__ */ - #endif /* __GNUC__ */ /* |