summaryrefslogtreecommitdiffstats
path: root/sys/amd64/include/floatingpoint.h
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1994-09-20 22:26:37 +0000
committerbde <bde@FreeBSD.org>1994-09-20 22:26:37 +0000
commita547491c3d664f958f17c58d4692e0465368adcc (patch)
treec8f752fd3cf3c1b7bd2dbacd60209a1802365022 /sys/amd64/include/floatingpoint.h
parent516108a214d464c523685f3be2bbc4169dee95d2 (diff)
downloadFreeBSD-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.
Diffstat (limited to 'sys/amd64/include/floatingpoint.h')
-rw-r--r--sys/amd64/include/floatingpoint.h46
1 files changed, 29 insertions, 17 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__ */
/*
OpenPOWER on IntegriCloud