merge in ics-release history after reset to master
diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index 965965f..ace8c1a 100644
--- a/libc/netbsd/net/getaddrinfo.c
+++ b/libc/netbsd/net/getaddrinfo.c
@@ -188,8 +188,8 @@
 #endif
 
 static const ns_src default_dns_files[] = {
-	{ NSSRC_FILES,	NS_SUCCESS },
-	{ NSSRC_DNS,	NS_SUCCESS },
+	{ NSSRC_FILES, 	NS_SUCCESS },
+	{ NSSRC_DNS, 	NS_SUCCESS },
 	{ 0, 0 }
 };
 
@@ -247,61 +247,61 @@
 	"Success",
 	"Address family for hostname not supported",	/* EAI_ADDRFAMILY */
 	"Temporary failure in name resolution",		/* EAI_AGAIN      */
-	"Invalid value for ai_flags",			/* EAI_BADFLAGS   */
-	"Non-recoverable failure in name resolution",	/* EAI_FAIL       */
+	"Invalid value for ai_flags",		       	/* EAI_BADFLAGS   */
+	"Non-recoverable failure in name resolution", 	/* EAI_FAIL       */
 	"ai_family not supported",			/* EAI_FAMILY     */
-	"Memory allocation failure",			/* EAI_MEMORY     */
-	"No address associated with hostname",		/* EAI_NODATA     */
+	"Memory allocation failure", 			/* EAI_MEMORY     */
+	"No address associated with hostname", 		/* EAI_NODATA     */
 	"hostname nor servname provided, or not known",	/* EAI_NONAME     */
 	"servname not supported for ai_socktype",	/* EAI_SERVICE    */
-	"ai_socktype not supported",			/* EAI_SOCKTYPE   */
-	"System error returned in errno",		/* EAI_SYSTEM     */
+	"ai_socktype not supported", 			/* EAI_SOCKTYPE   */
+	"System error returned in errno", 		/* EAI_SYSTEM     */
 	"Invalid value for hints",			/* EAI_BADHINTS	  */
 	"Resolved protocol is unknown",			/* EAI_PROTOCOL   */
 	"Argument buffer overflow",			/* EAI_OVERFLOW   */
-	"Unknown error",				/* EAI_MAX        */
+	"Unknown error", 				/* EAI_MAX        */
 };
 
 /* XXX macros that make external reference is BAD. */
 
-#define GET_AI(ai, afd, addr)					\
-do {								\
-	/* external reference: pai, error, and label free */	\
-	(ai) = get_ai(pai, (afd), (addr));			\
-	if ((ai) == NULL) {					\
-		error = EAI_MEMORY;				\
-		goto free;					\
-	}							\
+#define GET_AI(ai, afd, addr) 					\
+do { 								\
+	/* external reference: pai, error, and label free */ 	\
+	(ai) = get_ai(pai, (afd), (addr)); 			\
+	if ((ai) == NULL) { 					\
+		error = EAI_MEMORY; 				\
+		goto free; 					\
+	} 							\
 } while (/*CONSTCOND*/0)
 
-#define GET_PORT(ai, serv)					\
-do {								\
-	/* external reference: error and label free */		\
-	error = get_port((ai), (serv), 0);			\
-	if (error != 0)						\
-		goto free;					\
+#define GET_PORT(ai, serv) 					\
+do { 								\
+	/* external reference: error and label free */ 		\
+	error = get_port((ai), (serv), 0); 			\
+	if (error != 0) 					\
+		goto free; 					\
 } while (/*CONSTCOND*/0)
 
-#define GET_CANONNAME(ai, str)					\
-do {								\
-	/* external reference: pai, error and label free */	\
-	error = get_canonname(pai, (ai), (str));		\
-	if (error != 0)						\
-		goto free;					\
+#define GET_CANONNAME(ai, str) 					\
+do { 								\
+	/* external reference: pai, error and label free */ 	\
+	error = get_canonname(pai, (ai), (str)); 		\
+	if (error != 0) 					\
+		goto free; 					\
 } while (/*CONSTCOND*/0)
 
-#define ERR(err)						\
-do {								\
-	/* external reference: error, and label bad */		\
-	error = (err);						\
-	goto bad;						\
-	/*NOTREACHED*/						\
+#define ERR(err) 						\
+do { 								\
+	/* external reference: error, and label bad */ 		\
+	error = (err); 						\
+	goto bad; 						\
+	/*NOTREACHED*/ 						\
 } while (/*CONSTCOND*/0)
 
-#define MATCH_FAMILY(x, y, w)						\
-	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC ||	\
+#define MATCH_FAMILY(x, y, w) 						\
+	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == PF_UNSPEC || 	\
 	    (y) == PF_UNSPEC)))
-#define MATCH(x, y, w)							\
+#define MATCH(x, y, w) 							\
 	((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
 
 const char *
@@ -377,42 +377,26 @@
  * available, but whether addresses of the specified family are "configured
  * on the local system". However, bionic doesn't currently support getifaddrs,
  * so checking for connectivity is the next best thing.
- *
- * Note that simply checking connectivity is going to do the wrong thing on
- * multihomed devices.  Now we pass in a hint from the framework about what
- * to use for this request ("v4", "v4v6", or "v6").
  */
 static int
-_have_ipv6(const char *propvalue) {
-	if (*propvalue != 0) {
-		if ((strcmp(propvalue, "v4v6") == 0) || (strcmp(propvalue, "v6") == 0)) {
-			return 1;
-		} else {
-			return 0;
-		}
-	} else {
-		static const struct sockaddr_in6 sin6_test = {
-			.sin6_family = AF_INET6,
-			.sin6_addr.s6_addr = {  // 2000::
-				0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-			};
-		sockaddr_union addr = { .in6 = sin6_test };
-		return _test_connect(PF_INET6, &addr.generic, sizeof(addr.in6));
-	}
+_have_ipv6() {
+	static const struct sockaddr_in6 sin6_test = {
+		.sin6_family = AF_INET6,
+		.sin6_addr.s6_addr = {  // 2000::
+			0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+		};
+        sockaddr_union addr = { .in6 = sin6_test };
+	return _test_connect(PF_INET6, &addr.generic, sizeof(addr.in6));
 }
 
 static int
-_have_ipv4(const char *propvalue) {
-	if (*propvalue != 0) {
-		return (strncmp(propvalue, "v4", 2) == 0);
-	} else {
-		static const struct sockaddr_in sin_test = {
-			.sin_family = AF_INET,
-			.sin_addr.s_addr = __constant_htonl(0x08080808L)  // 8.8.8.8
-		};
-		sockaddr_union addr = { .in = sin_test };
-		return _test_connect(PF_INET, &addr.generic, sizeof(addr.in));
-	}
+_have_ipv4() {
+	static const struct sockaddr_in sin_test = {
+		.sin_family = AF_INET,
+		.sin_addr.s_addr = __constant_htonl(0x08080808L)  // 8.8.8.8
+	};
+        sockaddr_union addr = { .in = sin_test };
+        return _test_connect(PF_INET, &addr.generic, sizeof(addr.in));
 }
 
 // Returns 0 on success, else returns non-zero on error (in which case
@@ -1391,9 +1375,9 @@
 		}
 		cp += n;			/* name */
 		type = _getshort(cp);
-		cp += INT16SZ;			/* type */
+ 		cp += INT16SZ;			/* type */
 		class = _getshort(cp);
-		cp += INT16SZ + INT32SZ;	/* class, TTL */
+ 		cp += INT16SZ + INT32SZ;	/* class, TTL */
 		n = _getshort(cp);
 		cp += INT16SZ;			/* len */
 		if (class != C_IN) {
@@ -1632,8 +1616,8 @@
 		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
 			return 10;
 		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
-			   IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
-			   IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
+		           IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
+		           IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
 			return 1;
 		} else {
 			return 40;
@@ -1925,16 +1909,15 @@
 		q.anslen = sizeof(buf->buf);
 		int query_ipv6 = 1, query_ipv4 = 1;
 		if (pai->ai_flags & AI_ADDRCONFIG) {
-			/* check if the fwk gave us a hint */
-			char propname[PROP_NAME_MAX];
-			char propvalue[PROP_VALUE_MAX];
-			propvalue[0] = 0;
-			snprintf(propname, sizeof(propname), "net.dnsproto.%d", getpid());
-			if (__system_property_get(propname, propvalue) <= 0) {
-				__system_property_get("net.dnsproto", propvalue);
+			query_ipv6 = _have_ipv6();
+			query_ipv4 = _have_ipv4();
+			if (query_ipv6 == 0 && query_ipv4 == 0) {
+				// Both our IPv4 and IPv6 connectivity probes failed, which indicates
+				// that we have neither an IPv4 or an IPv6 default route (and thus no
+				// global IPv4 or IPv6 connectivity). We might be in a walled garden.
+				// Throw up our arms and ask for both A and AAAA.
+				query_ipv6 = query_ipv4 = 1;
 			}
-			query_ipv6 = _have_ipv6(propvalue);
-			query_ipv4 = _have_ipv4(propvalue);
 		}
 		if (query_ipv6) {
 			q.qtype = T_AAAA;
@@ -2360,7 +2343,7 @@
 			 * we only wanted one iteration of the loop, so stop.
 			 */
 			if (!(res->options & RES_DNSRCH))
-				done++;
+			        done++;
 		}
 	}
 
diff --git a/libm/i387/fenv.c b/libm/i387/fenv.c
index aabe270..89ddc55 100644
--- a/libm/i387/fenv.c
+++ b/libm/i387/fenv.c
@@ -31,16 +31,46 @@
 #include "npx.h"
 #include "fenv.h"
 
+/*
+ * As compared to the x87 control word, the SSE unit's control word
+ * has the rounding control bits offset by 3 and the exception mask
+ * bits offset by 7.
+ */
+#define	_SSE_ROUND_SHIFT	3
+#define	_SSE_EMASK_SHIFT	7
+
 const fenv_t __fe_dfl_env = {
-	__INITIAL_NPXCW__,
-	0x0000,
-	0x0000,
-	0x1f80,
-	0xffffffff,
+	__INITIAL_NPXCW__, /*__control*/
+	0x0000,            /*__mxcsr_hi*/
+	0x0000,            /*__status*/
+	0x1f80,            /*__mxcsr_lo*/
+	0xffffffff,        /*__tag*/
 	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff } /*__other*/
 };
 
+#define __fldcw(__cw)           __asm __volatile("fldcw %0" : : "m" (__cw))
+#define __fldenv(__env)         __asm __volatile("fldenv %0" : : "m" (__env))
+#define	__fldenvx(__env)	__asm __volatile("fldenv %0" : : "m" (__env)  \
+				: "st", "st(1)", "st(2)", "st(3)", "st(4)",   \
+				"st(5)", "st(6)", "st(7)")
+#define __fnclex()              __asm __volatile("fnclex")
+#define __fnstenv(__env)        __asm __volatile("fnstenv %0" : "=m" (*(__env)))
+#define __fnstcw(__cw)          __asm __volatile("fnstcw %0" : "=m" (*(__cw)))
+#define __fnstsw(__sw)          __asm __volatile("fnstsw %0" : "=am" (*(__sw)))
+#define __fwait()               __asm __volatile("fwait")
+#define __ldmxcsr(__csr)        __asm __volatile("ldmxcsr %0" : : "m" (__csr))
+#define __stmxcsr(__csr)        __asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
+
+/* After testing for SSE support once, we cache the result in __has_sse. */
+enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK };
+#ifdef __SSE__
+#define __HAS_SSE()     1
+#else
+#define __HAS_SSE()     (__has_sse == __SSE_YES ||                      \
+                         (__has_sse == __SSE_UNK && __test_sse()))
+#endif
+
 enum __sse_support __has_sse =
 #ifdef __SSE__
 	__SSE_YES;
@@ -48,6 +78,7 @@
 	__SSE_UNK;
 #endif
 
+#ifndef __SSE__
 #define	getfl(x)	__asm __volatile("pushfl\n\tpopl %0" : "=mr" (*(x)))
 #define	setfl(x)	__asm __volatile("pushl %0\n\tpopfl" : : "g" (x))
 #define	cpuid_dx(x)	__asm __volatile("pushl %%ebx\n\tmovl $1, %%eax\n\t"  \
@@ -82,23 +113,27 @@
 	__has_sse = __SSE_NO;
 	return (0);
 }
+#endif /* __SSE__ */
 
 int
 fesetexceptflag(const fexcept_t *flagp, int excepts)
 {
 	fenv_t env;
-	int mxcsr;
+	__uint32_t mxcsr;
 
-	__fnstenv(&env);
-	env.__status &= ~excepts;
-	env.__status |= *flagp & excepts;
-	__fldenv(env);
-
-	if (__HAS_SSE()) {
-		__stmxcsr(&mxcsr);
-		mxcsr &= ~excepts;
-		mxcsr |= *flagp & excepts;
-		__ldmxcsr(mxcsr);
+	excepts &= FE_ALL_EXCEPT;
+	if (excepts) { /* Do nothing if excepts is 0 */
+		__fnstenv(&env);
+		env.__status &= ~excepts;
+		env.__status |= *flagp & excepts;
+		__fnclex();
+		__fldenv(env);
+		if (__HAS_SSE()) {
+			__stmxcsr(&mxcsr);
+			mxcsr &= ~excepts;
+			mxcsr |= *flagp & excepts;
+			__ldmxcsr(mxcsr);
+		}
 	}
 
 	return (0);
@@ -117,32 +152,38 @@
 int
 fegetenv(fenv_t *envp)
 {
-	int control, mxcsr;
+	__uint32_t mxcsr;
 
-	/*
-	 * fnstenv masks all exceptions, so we need to save and
-	 * restore the control word to avoid this side effect.
-	 */
-	__fnstcw(&control);
 	__fnstenv(envp);
+	/*
+	 * fnstenv masks all exceptions, so we need to restore
+	 * the old control word to avoid this side effect.
+	 */
+	__fldcw(envp->__control);
 	if (__HAS_SSE()) {
 		__stmxcsr(&mxcsr);
-		__set_mxcsr(*envp, mxcsr);
+		envp->__mxcsr_hi = mxcsr >> 16;
+		envp->__mxcsr_lo = mxcsr & 0xffff;
 	}
-	__fldcw(control);
 	return (0);
 }
 
 int
 feholdexcept(fenv_t *envp)
 {
-	int mxcsr;
+	__uint32_t mxcsr;
+	fenv_t env;
 
-	__fnstenv(envp);
+	__fnstenv(&env);
+	*envp = env;
+	env.__status &= ~FE_ALL_EXCEPT;
+	env.__control |= FE_ALL_EXCEPT;
 	__fnclex();
+	__fldenv(env);
 	if (__HAS_SSE()) {
 		__stmxcsr(&mxcsr);
-		__set_mxcsr(*envp, mxcsr);
+		envp->__mxcsr_hi = mxcsr >> 16;
+		envp->__mxcsr_lo = mxcsr & 0xffff;
 		mxcsr &= ~FE_ALL_EXCEPT;
 		mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT;
 		__ldmxcsr(mxcsr);
@@ -153,60 +194,198 @@
 int
 feupdateenv(const fenv_t *envp)
 {
-	int mxcsr;
-	short status;
+	__uint32_t mxcsr;
+	__uint16_t status;
 
 	__fnstsw(&status);
-	if (__HAS_SSE())
+	if (__HAS_SSE()) {
 		__stmxcsr(&mxcsr);
-	else
+	} else {
 		mxcsr = 0;
+	}
 	fesetenv(envp);
 	feraiseexcept((mxcsr | status) & FE_ALL_EXCEPT);
 	return (0);
 }
 
 int
-__feenableexcept(int mask)
+feenableexcept(int mask)
 {
-	int mxcsr, control, omask;
+	__uint32_t mxcsr;
+	__uint16_t control, omask;
 
 	mask &= FE_ALL_EXCEPT;
 	__fnstcw(&control);
-	if (__HAS_SSE())
-		__stmxcsr(&mxcsr);
-	else
-		mxcsr = 0;
-	omask = (control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
-	control &= ~mask;
-	__fldcw(control);
 	if (__HAS_SSE()) {
-		mxcsr &= ~(mask << _SSE_EMASK_SHIFT);
-		__ldmxcsr(mxcsr);
+		__stmxcsr(&mxcsr);
+	} else {
+		mxcsr = 0;
 	}
-	return (~omask);
+	omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
+	if (mask) {
+		control &= ~mask;
+		__fldcw(control);
+		if (__HAS_SSE()) {
+			mxcsr &= ~(mask << _SSE_EMASK_SHIFT);
+			__ldmxcsr(mxcsr);
+		}
+	}
+	return (omask);
 }
 
 int
-__fedisableexcept(int mask)
+fedisableexcept(int mask)
 {
-	int mxcsr, control, omask;
+	__uint32_t mxcsr;
+	__uint16_t control, omask;
 
 	mask &= FE_ALL_EXCEPT;
 	__fnstcw(&control);
-	if (__HAS_SSE())
-		__stmxcsr(&mxcsr);
-	else
-		mxcsr = 0;
-	omask = (control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
-	control |= mask;
-	__fldcw(control);
 	if (__HAS_SSE()) {
-		mxcsr |= mask << _SSE_EMASK_SHIFT;
-		__ldmxcsr(mxcsr);
+		__stmxcsr(&mxcsr);
+	} else {
+		mxcsr = 0;
 	}
-	return (~omask);
+	omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
+	if (mask) {
+		control |= mask;
+		__fldcw(control);
+		if (__HAS_SSE()) {
+			mxcsr |= mask << _SSE_EMASK_SHIFT;
+			__ldmxcsr(mxcsr);
+		}
+	}
+	return (omask);
 }
 
-__weak_reference(__feenableexcept, feenableexcept);
-__weak_reference(__fedisableexcept, fedisableexcept);
+int
+feclearexcept(int excepts)
+{
+	fenv_t env;
+	__uint32_t mxcsr;
+
+	excepts &= FE_ALL_EXCEPT;
+	if (excepts) { /* Do nothing if excepts is 0 */
+		__fnstenv(&env);
+		env.__status &= ~excepts;
+		__fnclex();
+		__fldenv(env);
+		if (__HAS_SSE()) {
+			__stmxcsr(&mxcsr);
+			mxcsr &= ~excepts;
+			__ldmxcsr(mxcsr);
+		}
+	}
+	return (0);
+}
+
+int
+fegetexceptflag(fexcept_t *flagp, int excepts)
+{
+	__uint32_t mxcsr;
+	__uint16_t status;
+
+	excepts &= FE_ALL_EXCEPT;
+	__fnstsw(&status);
+	if (__HAS_SSE()) {
+		__stmxcsr(&mxcsr);
+	} else {
+		mxcsr = 0;
+	}
+	*flagp = (status | mxcsr) & excepts;
+	return (0);
+}
+
+int
+fetestexcept(int excepts)
+{
+	__uint32_t mxcsr;
+	__uint16_t status;
+
+	excepts &= FE_ALL_EXCEPT;
+	if (excepts) { /* Do nothing if excepts is 0 */
+		__fnstsw(&status);
+		if (__HAS_SSE()) {
+			__stmxcsr(&mxcsr);
+		} else {
+			mxcsr = 0;
+		}
+		return ((status | mxcsr) & excepts);
+	}
+	return (0);
+}
+
+int
+fegetround(void)
+{
+	__uint16_t control;
+
+	/*
+	 * We assume that the x87 and the SSE unit agree on the
+	 * rounding mode.  Reading the control word on the x87 turns
+	 * out to be about 5 times faster than reading it on the SSE
+	 * unit on an Opteron 244.
+	 */
+	__fnstcw(&control);
+	return (control & _ROUND_MASK);
+}
+
+int
+fesetround(int round)
+{
+	__uint32_t mxcsr;
+	__uint16_t control;
+
+	if (round & ~_ROUND_MASK) {
+		return (-1);
+	} else {
+		__fnstcw(&control);
+		control &= ~_ROUND_MASK;
+		control |= round;
+		__fldcw(control);
+		if (__HAS_SSE()) {
+			__stmxcsr(&mxcsr);
+			mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
+			mxcsr |= round << _SSE_ROUND_SHIFT;
+			__ldmxcsr(mxcsr);
+		}
+		return (0);
+	}
+}
+
+int
+fesetenv(const fenv_t *envp)
+{
+	fenv_t env = *envp;
+	__uint32_t mxcsr;
+
+	mxcsr = (env.__mxcsr_hi << 16) | (env.__mxcsr_lo);
+	env.__mxcsr_hi = 0xffff;
+	env.__mxcsr_lo = 0xffff;
+	/*
+	 * XXX Using fldenvx() instead of fldenv() tells the compiler that this
+	 * instruction clobbers the i387 register stack.  This happens because
+	 * we restore the tag word from the saved environment.  Normally, this
+	 * would happen anyway and we wouldn't care, because the ABI allows
+	 * function calls to clobber the i387 regs.  However, fesetenv() is
+	 * inlined, so we need to be more careful.
+	 */
+	__fldenvx(env);
+	if (__HAS_SSE()) {
+		__ldmxcsr(mxcsr);
+	}
+	return (0);
+}
+
+int
+fegetexcept(void)
+{
+	__uint16_t control;
+
+	/*
+	 * We assume that the masks for the x87 and the SSE unit are
+	 * the same.
+	 */
+	__fnstcw(&control);
+	return (~control & FE_ALL_EXCEPT);
+}
diff --git a/libm/include/i387/fenv.h b/libm/include/i387/fenv.h
index 5fe64e2..710494c 100644
--- a/libm/include/i387/fenv.h
+++ b/libm/include/i387/fenv.h
@@ -45,13 +45,6 @@
 	char		__other[16];
 } fenv_t;
 
-#define	__get_mxcsr(env)	(((env).__mxcsr_hi << 16) |	\
-				 ((env).__mxcsr_lo))
-#define	__set_mxcsr(env, x)	do {				\
-	(env).__mxcsr_hi = (__uint32_t)(x) >> 16;		\
-	(env).__mxcsr_lo = (__uint16_t)(x);			\
-} while (0)
-
 typedef	__uint16_t	fexcept_t;
 
 /* Exception flags */
@@ -72,168 +65,35 @@
 #define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
 			 FE_UPWARD | FE_TOWARDZERO)
 
-/*
- * As compared to the x87 control word, the SSE unit's control word
- * has the rounding control bits offset by 3 and the exception mask
- * bits offset by 7.
- */
-#define	_SSE_ROUND_SHIFT	3
-#define	_SSE_EMASK_SHIFT	7
-
-/* After testing for SSE support once, we cache the result in __has_sse. */
-enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK };
-extern enum __sse_support __has_sse;
-int __test_sse(void);
-#ifdef __SSE__
-#define	__HAS_SSE()	1
-#else
-#define	__HAS_SSE()	(__has_sse == __SSE_YES ||			\
-			 (__has_sse == __SSE_UNK && __test_sse()))
-#endif
-
 __BEGIN_DECLS
 
 /* Default floating-point environment */
 extern const fenv_t	__fe_dfl_env;
 #define	FE_DFL_ENV	(&__fe_dfl_env)
 
-#define	__fldcw(__cw)		__asm __volatile("fldcw %0" : : "m" (__cw))
-#define	__fldenv(__env)		__asm __volatile("fldenv %0" : : "m" (__env))
-#define	__fnclex()		__asm __volatile("fnclex")
-#define	__fnstenv(__env)	__asm __volatile("fnstenv %0" : "=m" (*(__env)))
-#define	__fnstcw(__cw)		__asm __volatile("fnstcw %0" : "=m" (*(__cw)))
-#define	__fnstsw(__sw)		__asm __volatile("fnstsw %0" : "=a" (*(__sw)))
-#define	__fwait()		__asm __volatile("fwait")
-#define	__ldmxcsr(__csr)	__asm __volatile("ldmxcsr %0" : : "m" (__csr))
-#define	__stmxcsr(__csr)	__asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
+/* C99 floating-point exception functions */
+int feclearexcept(int excepts);
+int fegetexceptflag(fexcept_t *flagp, int excepts);
+int fesetexceptflag(const fexcept_t *flagp, int excepts);
+/* feraiseexcept does not set the inexact flag on overflow/underflow */
+int feraiseexcept(int excepts);
+int fetestexcept(int excepts);
 
-static __inline int
-feclearexcept(int __excepts)
-{
-	fenv_t __env;
-	int __mxcsr;
+/* C99 rounding control functions */
+int fegetround(void);
+int fesetround(int round);
 
-	if (__excepts == FE_ALL_EXCEPT) {
-		__fnclex();
-	} else {
-		__fnstenv(&__env);
-		__env.__status &= ~__excepts;
-		__fldenv(__env);
-	}
-	if (__HAS_SSE()) {
-		__stmxcsr(&__mxcsr);
-		__mxcsr &= ~__excepts;
-		__ldmxcsr(__mxcsr);
-	}
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	int __mxcsr;
-	short __status;
-
-	__fnstsw(&__status);
-	if (__HAS_SSE())
-		__stmxcsr(&__mxcsr);
-	else
-		__mxcsr = 0;
-	*__flagp = (__mxcsr | __status) & __excepts;
-	return (0);
-}
-
-int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
-int feraiseexcept(int __excepts);
-
-static __inline int
-fetestexcept(int __excepts)
-{
-	int __mxcsr;
-	short __status;
-
-	__fnstsw(&__status);
-	if (__HAS_SSE())
-		__stmxcsr(&__mxcsr);
-	else
-		__mxcsr = 0;
-	return ((__status | __mxcsr) & __excepts);
-}
-
-static __inline int
-fegetround(void)
-{
-	int __control;
-
-	/*
-	 * We assume that the x87 and the SSE unit agree on the
-	 * rounding mode.  Reading the control word on the x87 turns
-	 * out to be about 5 times faster than reading it on the SSE
-	 * unit on an Opteron 244.
-	 */
-	__fnstcw(&__control);
-	return (__control & _ROUND_MASK);
-}
-
-static __inline int
-fesetround(int __round)
-{
-	int __mxcsr, __control;
-
-	if (__round & ~_ROUND_MASK)
-		return (-1);
-
-	__fnstcw(&__control);
-	__control &= ~_ROUND_MASK;
-	__control |= __round;
-	__fldcw(__control);
-
-	if (__HAS_SSE()) {
-		__stmxcsr(&__mxcsr);
-		__mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
-		__mxcsr |= __round << _SSE_ROUND_SHIFT;
-		__ldmxcsr(__mxcsr);
-	}
-
-	return (0);
-}
-
+/* C99 floating-point environment functions */
 int fegetenv(fenv_t *__envp);
 int feholdexcept(fenv_t *__envp);
-
-static __inline int
-fesetenv(const fenv_t *__envp)
-{
-	fenv_t __env = *__envp;
-	int __mxcsr;
-
-	__mxcsr = __get_mxcsr(__env);
-	__set_mxcsr(__env, 0xffffffff);
-	__fldenv(__env);
-	if (__HAS_SSE())
-		__ldmxcsr(__mxcsr);
-	return (0);
-}
-
+int fesetenv(const fenv_t *envp);
 int feupdateenv(const fenv_t *__envp);
 
 #if __BSD_VISIBLE
-
+/* Additional support functions to set/query floating point traps */
 int feenableexcept(int __mask);
 int fedisableexcept(int __mask);
-
-static __inline int
-fegetexcept(void)
-{
-	int __control;
-
-	/*
-	 * We assume that the masks for the x87 and the SSE unit are
-	 * the same.
-	 */
-	__fnstcw(&__control);
-	return (~__control & FE_ALL_EXCEPT);
-}
+int fegetexcept(void);
 
 #endif /* __BSD_VISIBLE */