From 8793135f2d9a7040f623f0618c042d5f5add8897 Mon Sep 17 00:00:00 2001 From: Bruce Evans Date: Tue, 20 Sep 1994 22:26:37 +0000 Subject: [PATCH] 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. --- sys/amd64/include/floatingpoint.h | 48 +++++++++++++++++++------------ sys/i386/include/floatingpoint.h | 48 +++++++++++++++++++------------ 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/sys/amd64/include/floatingpoint.h b/sys/amd64/include/floatingpoint.h index 182e5a386db0..69cb204c835c 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 $ - */ - -/* - * IEEE floating point structure and function definitions + * $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 + */ + +/*- + * XXX the following undocumented pollution is exported: + * fpsetsticky(). + * FP*FLD, FP*OFF and FP*REG from + */ + #include #include #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 182e5a386db0..69cb204c835c 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 $ - */ - -/* - * IEEE floating point structure and function definitions + * $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 + */ + +/*- + * XXX the following undocumented pollution is exported: + * fpsetsticky(). + * FP*FLD, FP*OFF and FP*REG from + */ + #include #include #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__ */ /*