Merge "Adjust symbol lookup for DT_SYMBOLIC case"
diff --git a/libc/bionic/libc_init_common.c b/libc/bionic/libc_init_common.c
index 6508c0b..fb164f4 100644
--- a/libc/bionic/libc_init_common.c
+++ b/libc/bionic/libc_init_common.c
@@ -40,10 +40,10 @@
 #include <errno.h>
 
 extern unsigned __get_sp(void);
-extern pid_t    gettid(void);
+extern pid_t gettid(void);
 
 char*  __progname;
-char **environ;
+char** environ;
 
 /* from asm/page.h */
 unsigned int __page_size = PAGE_SIZE;
@@ -60,48 +60,42 @@
  * stores the pointer in TLS, but does not add it to pthread's gThreadList. This
  * has to be done later from libc itself (see __libc_init_common).
  *
- * This function also stores elfdata argument in a specific TLS slot to be later
+ * This function also stores the elf_data argument in a specific TLS slot to be later
  * picked up by the libc constructor.
  */
-void __libc_init_tls(unsigned** elfdata)
-{
-    pthread_attr_t             thread_attr;
-    static pthread_internal_t  thread;
-    static void*               tls_area[BIONIC_TLS_SLOTS];
+void __libc_init_tls(unsigned** elf_data) {
+  unsigned stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
+  unsigned stack_size = 128 * 1024;
+  unsigned stack_bottom = stack_top - stack_size;
 
-    /* setup pthread runtime and main thread descriptor */
-    unsigned stacktop = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
-    unsigned stacksize = 128 * 1024;
-    unsigned stackbottom = stacktop - stacksize;
+  pthread_attr_t thread_attr;
+  pthread_attr_init(&thread_attr);
+  pthread_attr_setstack(&thread_attr, (void*) stack_bottom, stack_size);
 
-    pthread_attr_init(&thread_attr);
-    pthread_attr_setstack(&thread_attr, (void*)stackbottom, stacksize);
-    _init_thread(&thread, gettid(), &thread_attr, (void*)stackbottom, false);
-    __init_tls(tls_area, &thread);
+  static pthread_internal_t thread;
+  _init_thread(&thread, gettid(), &thread_attr, (void*) stack_bottom, false);
 
-    tls_area[TLS_SLOT_BIONIC_PREINIT] = elfdata;
+  static void* tls_area[BIONIC_TLS_SLOTS];
+  __init_tls(tls_area, &thread);
+  tls_area[TLS_SLOT_BIONIC_PREINIT] = elf_data;
 }
 
-void __libc_init_common(uintptr_t *elfdata)
-{
-    int     argc = *elfdata;
-    char**  argv = (char**)(elfdata + 1);
-    char**  envp = argv + argc + 1;
+void __libc_init_common(uintptr_t* elf_data) {
+  int argc = *elf_data;
+  char** argv = (char**) (elf_data + 1);
+  char** envp = argv + argc + 1;
 
-    /* get the initial thread from TLS and add it to gThreadList */
-    _pthread_internal_add(__get_thread());
+  // Get the main thread from TLS and add it to the thread list.
+  pthread_internal_t* main_thread = __get_thread();
+  main_thread->allocated_on_heap = false;
+  _pthread_internal_add(main_thread);
 
-    /* clear errno */
-    errno = 0;
+  // Set various globals.
+  errno = 0;
+  __progname = argv[0] ? argv[0] : "<unknown>";
+  environ = envp;
 
-    /* set program name */
-    __progname = argv[0] ? argv[0] : "<unknown>";
-
-    /* setup environment pointer */
-    environ = envp;
-
-    /* setup system properties - requires environment */
-    __system_properties_init();
+  __system_properties_init(); // Requires 'environ'.
 }
 
 /* This function will be called during normal program termination
@@ -111,39 +105,42 @@
  * 'fini_array' points to a list of function addresses. The first
  * entry in the list has value -1, the last one has value 0.
  */
-void __libc_fini(void* array)
-{
-    int count;
-    void** fini_array = array;
-    const size_t  minus1 = ~(size_t)0; /* ensure proper sign extension */
+void __libc_fini(void* array) {
+  void** fini_array = array;
+  const size_t minus1 = ~(size_t)0; /* ensure proper sign extension */
 
-    /* Sanity check - first entry must be -1 */
-    if (array == NULL || (size_t)fini_array[0] != minus1) {
-        return;
+  /* Sanity check - first entry must be -1 */
+  if (array == NULL || (size_t)fini_array[0] != minus1) {
+    return;
+  }
+
+  /* skip over it */
+  fini_array += 1;
+
+  /* Count the number of destructors. */
+  int count = 0;
+  while (fini_array[count] != NULL) {
+    ++count;
+  }
+
+  /* Now call each destructor in reverse order. */
+  while (count > 0) {
+    void (*func)() = (void (*)) fini_array[--count];
+
+    /* Sanity check, any -1 in the list is ignored */
+    if ((size_t)func == minus1) {
+      continue;
     }
 
-    /* skip over it */
-    fini_array += 1;
-
-    /* Count the number of destructors. */
-    for (count = 0; fini_array[count] != NULL; count++);
-
-    /* Now call each destructor in reverse order. */
-    while (count > 0) {
-        void (*func)() = (void (*)) fini_array[--count];
-
-        /* Sanity check, any -1 in the list is ignored */
-        if ((size_t)func == minus1)
-            continue;
-
-        func();
-    }
+    func();
+  }
 
 #ifndef LIBC_STATIC
-    {
-        extern void __libc_postfini(void) __attribute__((weak));
-        if (__libc_postfini)
-            __libc_postfini();
+  {
+    extern void __libc_postfini(void) __attribute__((weak));
+    if (__libc_postfini) {
+      __libc_postfini();
     }
+  }
 #endif
 }
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index 791a772..d8d0d05 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -105,44 +105,41 @@
 static pthread_mutex_t gThreadListLock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t gDebuggerNotificationLock = PTHREAD_MUTEX_INITIALIZER;
 
-
-static void
-_pthread_internal_free(pthread_internal_t* thread)
-{
-    if (thread != NULL) {
-        free(thread);
-    }
-}
-
-
-static void
-_pthread_internal_remove_locked( pthread_internal_t*  thread )
-{
+static void _pthread_internal_remove_locked(pthread_internal_t* thread) {
+  if (thread->next != NULL) {
     thread->next->prev = thread->prev;
-    thread->prev[0]    = thread->next;
+  }
+  if (thread->prev != NULL) {
+    thread->prev->next = thread->next;
+  } else {
+    gThreadList = thread->next;
+  }
+
+  // The main thread is not heap-allocated. See __libc_init_tls for the declaration,
+  // and __libc_init_common for the point where it's added to the thread list.
+  if (thread->allocated_on_heap) {
+    free(thread);
+  }
 }
 
-static void
-_pthread_internal_remove( pthread_internal_t*  thread )
-{
-    pthread_mutex_lock(&gThreadListLock);
-    _pthread_internal_remove_locked(thread);
-    pthread_mutex_unlock(&gThreadListLock);
+static void _pthread_internal_remove(pthread_internal_t* thread) {
+  pthread_mutex_lock(&gThreadListLock);
+  _pthread_internal_remove_locked(thread);
+  pthread_mutex_unlock(&gThreadListLock);
 }
 
-__LIBC_ABI_PRIVATE__ void
-_pthread_internal_add(pthread_internal_t* thread)
-{
-    pthread_mutex_lock(&gThreadListLock);
+__LIBC_ABI_PRIVATE__ void _pthread_internal_add(pthread_internal_t* thread) {
+  pthread_mutex_lock(&gThreadListLock);
 
-    thread->prev = &gThreadList;
-    thread->next = *(thread->prev);
-    if (thread->next != NULL) {
-        thread->next->prev = &thread->next;
-    }
-    *(thread->prev) = thread;
+  // We insert at the head.
+  thread->next = gThreadList;
+  thread->prev = NULL;
+  if (thread->next != NULL) {
+    thread->next->prev = thread;
+  }
+  gThreadList = thread;
 
-    pthread_mutex_unlock(&gThreadListLock);
+  pthread_mutex_unlock(&gThreadListLock);
 }
 
 __LIBC_ABI_PRIVATE__ pthread_internal_t*
@@ -312,6 +309,7 @@
     if (thread == NULL) {
         return ENOMEM;
     }
+    thread->allocated_on_heap = true;
 
     if (attr == NULL) {
         attr = &gDefaultPthreadAttr;
@@ -323,7 +321,7 @@
     if (stack == NULL) {
         stack = mkstack(stack_size, attr->guard_size);
         if (stack == NULL) {
-            _pthread_internal_free(thread);
+            free(thread);
             return ENOMEM;
         }
     }
@@ -353,7 +351,7 @@
         if (stack != attr->stack_base) {
             munmap(stack, stack_size);
         }
-        _pthread_internal_free(thread);
+        free(thread);
         errno = old_errno;
         return clone_errno;
     }
@@ -585,7 +583,6 @@
     // otherwise, keep it in memory and signal any joiners.
     if (thread->attr.flags & PTHREAD_ATTR_FLAG_DETACHED) {
         _pthread_internal_remove(thread);
-        _pthread_internal_free(thread);
     } else {
         pthread_mutex_lock(&gThreadListLock);
 
@@ -677,7 +674,6 @@
      */
     if (count <= 0) {
         _pthread_internal_remove_locked(thread);
-        _pthread_internal_free(thread);
     }
     pthread_mutex_unlock(&gThreadListLock);
     return 0;
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index a6b44c7..bc68291 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -36,9 +36,10 @@
 typedef struct pthread_internal_t
 {
     struct pthread_internal_t*  next;
-    struct pthread_internal_t** prev;
+    struct pthread_internal_t*  prev;
     pthread_attr_t              attr;
     pid_t                       kernel_id;
+    bool                        allocated_on_heap;
     pthread_cond_t              join_cond;
     int                         join_count;
     void*                       return_value;
diff --git a/libm/Makefile-orig b/libm/Makefile-orig
deleted file mode 100644
index 46dd095..0000000
--- a/libm/Makefile-orig
+++ /dev/null
@@ -1,158 +0,0 @@
-#  @(#)Makefile 5.1beta 93/09/24
-# $FreeBSD: src/lib/msun/Makefile,v 1.74 2005/11/06 17:59:40 bde Exp $
-#
-#  ====================================================
-#  Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-#
-#  Developed at SunPro, a Sun Microsystems, Inc. business.
-#  Permission to use, copy, modify, and distribute this
-#  software is freely granted, provided that this notice
-#  is preserved.
-#  ====================================================
-#
-#
-
-.if ${MACHINE_ARCH} == "i386"
-ARCH_SUBDIR= i387
-.else
-ARCH_SUBDIR= ${MACHINE_ARCH}
-.endif
-
-.include "${ARCH_SUBDIR}/Makefile.inc"
-
-.PATH:	${.CURDIR}/bsdsrc
-.PATH:	${.CURDIR}/man
-.PATH:	${.CURDIR}/src
-
-LIB=	m
-SHLIBDIR?= /lib
-SHLIB_MAJOR= 4
-COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \
-	e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_asin.c e_asinf.c \
-	e_atan2.c e_atan2f.c e_atanh.c e_atanhf.c e_cosh.c e_coshf.c e_exp.c \
-	e_expf.c e_fmod.c e_fmodf.c e_gamma.c e_gamma_r.c e_gammaf.c \
-	e_gammaf_r.c e_hypot.c e_hypotf.c e_j0.c e_j0f.c e_j1.c e_j1f.c \
-	e_jn.c e_jnf.c e_lgamma.c e_lgamma_r.c e_lgammaf.c e_lgammaf_r.c \
-	e_log.c e_log10.c e_log10f.c e_logf.c e_pow.c e_powf.c e_rem_pio2.c \
-	e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c e_scalbf.c \
-	e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c fenv.c \
-	k_cos.c k_cosf.c k_rem_pio2.c k_sin.c k_sinf.c \
-	k_tan.c k_tanf.c \
-	s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_cbrt.c s_cbrtf.c \
-	s_ceil.c s_ceilf.c s_ceill.c \
-	s_copysign.c s_copysignf.c s_cos.c s_cosf.c s_erf.c s_erff.c \
-	s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c s_fabsf.c s_fdim.c \
-	s_finite.c s_finitef.c \
-	s_floor.c s_floorf.c s_floorl.c s_fma.c s_fmaf.c \
-	s_fmax.c s_fmaxf.c s_fmaxl.c s_fmin.c \
-	s_fminf.c s_fminl.c s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \
-	s_ilogbl.c s_isfinite.c s_isnan.c s_isnormal.c \
-	s_llrint.c s_llrintf.c s_llround.c s_llroundf.c s_llroundl.c \
-	s_log1p.c s_log1pf.c s_logb.c s_logbf.c s_lrint.c s_lrintf.c \
-	s_lround.c s_lroundf.c s_lroundl.c s_modff.c \
-	s_nearbyint.c s_nextafter.c s_nextafterf.c \
-	s_nexttowardf.c s_remquo.c s_remquof.c \
-	s_rint.c s_rintf.c s_round.c s_roundf.c s_roundl.c \
-	s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \
-	s_signgam.c s_significand.c s_significandf.c s_sin.c s_sinf.c s_tan.c \
-	s_tanf.c s_tanh.c s_tanhf.c s_trunc.c s_truncf.c s_truncl.c \
-	w_cabs.c w_cabsf.c w_drem.c w_dremf.c
-
-# Location of fpmath.h and _fpmath.h
-LIBCDIR=	${.CURDIR}/../libc
-CFLAGS+=	-I${LIBCDIR}/include -I${LIBCDIR}/${MACHINE_ARCH}
-
-# C99 long double functions
-COMMON_SRCS+=	s_copysignl.c s_fabsl.c
-.if ${LDBL_PREC} != 53
-# If long double != double use these; otherwise, we alias the double versions.
-COMMON_SRCS+=	s_fmal.c s_frexpl.c s_nextafterl.c s_nexttoward.c s_scalbnl.c
-.endif
-
-# C99 complex functions
-COMMON_SRCS+=	s_cimag.c s_cimagf.c s_cimagl.c s_conj.c s_conjf.c s_conjl.c \
-	s_creal.c s_crealf.c s_creall.c
-
-# FreeBSD's C library supplies these functions:
-#COMMON_SRCS+=	s_fabs.c s_frexp.c s_isnan.c s_ldexp.c s_modf.c
-
-# Exclude the generic versions of what we provide in the MD area.
-.PATH:	${.CURDIR}/${ARCH_SUBDIR}
-.if defined(ARCH_SRCS)
-.for i in ${ARCH_SRCS}
-COMMON_SRCS:=  ${COMMON_SRCS:N${i:R}.c}
-.endfor
-.endif
-
-SRCS=	${COMMON_SRCS} ${ARCH_SRCS}
-
-INCS=	fenv.h math.h
-
-MAN=	acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 ceil.3 \
-	cimag.3 copysign.3 cos.3 cosh.3 erf.3 exp.3 fabs.3 fdim.3 \
-	feclearexcept.3 feenableexcept.3 fegetenv.3 \
-	fegetround.3 fenv.3 floor.3 \
-	fma.3 fmax.3 fmod.3 hypot.3 ieee.3 ieee_test.3 ilogb.3 j0.3 \
-	lgamma.3 lrint.3 lround.3 math.3 nextafter.3 remainder.3 rint.3 \
-	round.3 scalbn.3 signbit.3 sin.3 sinh.3 sqrt.3 tan.3 tanh.3 trunc.3
-
-MLINKS+=acos.3 acosf.3
-MLINKS+=acosh.3 acoshf.3
-MLINKS+=asin.3 asinf.3
-MLINKS+=asinh.3 asinhf.3
-MLINKS+=atan.3 atanf.3
-MLINKS+=atanh.3 atanhf.3
-MLINKS+=atan2.3 atan2f.3
-MLINKS+=ceil.3 ceilf.3 ceil.3 ceill.3
-MLINKS+=cimag.3 cimagf.3 cimag.3 cimagl.3 \
-	cimag.3 conj.3 cimag.3 conjf.3 cimag.3 conjl.3 \
-	cimag.3 creal.3 cimag.3 crealf.3 cimag.3 creall.3
-MLINKS+=copysign.3 copysignf.3 copysign.3 copysignl.3
-MLINKS+=cos.3 cosf.3
-MLINKS+=cosh.3 coshf.3
-MLINKS+=erf.3 erfc.3 erf.3 erff.3 erf.3 erfcf.3
-MLINKS+=exp.3 expm1.3 exp.3 log.3 exp.3 log10.3 exp.3 log1p.3 exp.3 pow.3 \
-	exp.3 exp2.3 exp.3 exp2f.3 exp.3 expf.3 \
-	exp.3 expm1f.3 exp.3 logf.3 exp.3 powf.3 \
-	exp.3 log10f.3 exp.3 log1pf.3
-MLINKS+=fabs.3 fabsf.3 fabs.3 fabsl.3
-MLINKS+=fdim.3 fdimf.3 fdim.3 fdiml.3
-MLINKS+=feclearexcept.3 fegetexceptflag.3 feclearexcept.3 feraiseexcept.3 \
-	feclearexcept.3 fesetexceptflag.3 feclearexcept.3 fetestexcept.3
-MLINKS+=feenableexcept.3 fedisableexcept.3 feenableexcept.3 fegetexcept.3
-MLINKS+=fegetenv.3 feholdexcept.3 fegetenv.3 fesetenv.3 \
-	fegetenv.3 feupdateenv.3
-MLINKS+=fegetround.3 fesetround.3
-MLINKS+=floor.3 floorf.3 floor.3 floorl.3
-MLINKS+=fma.3 fmaf.3 fma.3 fmal.3
-MLINKS+=fmax.3 fmaxf.3 fmax.3 fmaxl.3 \
-	fmax.3 fmin.3 fmax.3 fminf.3 fmax.3 fminl.3
-MLINKS+=fmod.3 fmodf.3
-MLINKS+=hypot.3 cabs.3 hypot.3 cabsf.3 hypot.3 hypotf.3
-MLINKS+=ieee_test.3 scalb.3 ieee_test.3 scalbf.3
-MLINKS+=ieee_test.3 significand.3 ieee_test.3 significandf.3
-MLINKS+=ilogb.3 ilogbf.3 ilogb.3 ilogbl.3 \
-	ilogb.3 logb.3 ilogb.3 logbf.3
-MLINKS+=j0.3 j1.3 j0.3 jn.3 j0.3 y0.3 j0.3 y1.3 j0.3 y1f.3 j0.3 yn.3
-MLINKS+=j0.3 j0f.3 j0.3 j1f.3 j0.3 jnf.3 j0.3 y0f.3 j0.3 ynf.3
-MLINKS+=lgamma.3 gamma.3 lgamma.3 gammaf.3 lgamma.3 lgammaf.3 lgamma.3 tgamma.3
-MLINKS+=lrint.3 llrint.3 lrint.3 llrintf.3 lrint.3 lrintf.3
-MLINKS+=lround.3 llround.3 lround.3 llroundf.3 lround.3 llroundl.3 \
-	lround.3 lroundf.3 lround.3 lroundl.3
-MLINKS+=nextafter.3 nextafterf.3 nextafter.3 nextafterl.3
-MLINKS+=nextafter.3 nexttoward.3 nextafter.3 nexttowardf.3
-MLINKS+=nextafter.3 nexttowardl.3
-MLINKS+=remainder.3 remainderf.3
-MLINKS+=remainder.3 remquo.3 remainder.3 remquof.3
-MLINKS+=rint.3 rintf.3 rint.3 nearbyint.3 rint.3 nearbyintf.3
-MLINKS+=round.3 roundf.3 round.3 roundl.3
-MLINKS+=scalbn.3 scalbln.3 scalbn.3 scalblnf.3 scalbn.3 scalblnl.3
-MLINKS+=scalbn.3 scalbnf.3 scalbn.3 scalbnl.3
-MLINKS+=sin.3 sinf.3
-MLINKS+=sinh.3 sinhf.3
-MLINKS+=sqrt.3 cbrt.3 sqrt.3 cbrtf.3 sqrt.3 sqrtf.3
-MLINKS+=tan.3 tanf.3
-MLINKS+=tanh.3 tanhf.3
-MLINKS+=trunc.3 truncf.3 trunc.3 truncl.3
-
-.include <bsd.lib.mk>
diff --git a/libm/alpha/Makefile.inc b/libm/alpha/Makefile.inc
deleted file mode 100644
index f75ace9..0000000
--- a/libm/alpha/Makefile.inc
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD: src/lib/msun/alpha/Makefile.inc,v 1.2 2005/03/07 04:53:35 das Exp $
-
-ARCH_SRCS = s_copysign.S s_copysignf.S
-LDBL_PREC = 53
-
-# XXX Comment from NetBSD/Alpha:
-# XXX LINT SIGFPEs in e_exp.c's strtod().  FP underflow/denorm software
-# handling is broken (doesn't exist!) on the Alpha port.
-# Stock gcc 2.7.2.1 doesn't understand these options.
-#CFLAGS += -mtrap-precision=i -mfp-trap-mode=su
diff --git a/libm/alpha/_fpmath.h b/libm/alpha/_fpmath.h
deleted file mode 100644
index cfa235c..0000000
--- a/libm/alpha/_fpmath.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-
- * Copyright (c) 2002, 2003 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libc/alpha/_fpmath.h,v 1.6 2005/03/07 04:55:21 das Exp $
- */
-
-union IEEEl2bits {
-	long double	e;
-	struct {
-		unsigned int	manl	:32;
-		unsigned int	manh	:20;
-		unsigned int	exp	:11;
-		unsigned int	sign	:1;
-	} bits;
-};
-
-#define	mask_nbit_l(u)	((void)0)
-#define	LDBL_IMPLICIT_NBIT
-#define	LDBL_NBIT	0
-
-#define	LDBL_MANH_SIZE	20
-#define	LDBL_MANL_SIZE	32
-
-#define	LDBL_TO_ARRAY32(u, a) do {			\
-	(a)[0] = (uint32_t)(u).bits.manl;		\
-	(a)[1] = (uint32_t)(u).bits.manh;		\
-} while(0)
diff --git a/libm/alpha/fenv.c b/libm/alpha/fenv.c
deleted file mode 100644
index e8ab204..0000000
--- a/libm/alpha/fenv.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/alpha/fenv.c,v 1.2 2005/03/16 19:03:44 das Exp $
- */
-
-#include <sys/cdefs.h>
-#include <machine/sysarch.h>
-#include <fenv.h>
-
-const fenv_t __fe_dfl_env = 0x680e000000000000ULL;
-
-struct mask_args {
-	fenv_t mask;
-};
-
-/*
- * The lower 49 bits of the FPCR are unused by the hardware, so we use
- * the lower order bits to store the kernel's idea of the FP mask as
- * described in the Alpha Architecture Manual.
- */
-int
-fegetenv(fenv_t *envp)
-{
-	struct mask_args p;
-	union __fpcr r;
-
-	/*
-	 * The syscall acts as an implicit exception barrier, so we
-	 * only need to issue an excb after the mf_fpcr to ensure that
-	 * the read is executed before any subsequent FP ops.
-	 */
-	sysarch(ALPHA_GET_FPMASK, (char *)&p);
-	__mf_fpcr(&r.__d);
-	*envp = r.__bits | p.mask;
-	__excb();
-	return (0);
-}
-
-int
-feholdexcept(fenv_t *envp)
-{
-	struct mask_args p;
-	union __fpcr r;
-
-	sysarch(ALPHA_GET_FPMASK, (char *)&p);
-	__mf_fpcr(&r.__d);
-	*envp = r.__bits | p.mask;
-	r.__bits &= ~((fenv_t)FE_ALL_EXCEPT << _FPUSW_SHIFT);
-	__mt_fpcr(r.__d);
-	if (p.mask & FE_ALL_EXCEPT) {
-		p.mask = 0;
-		sysarch(ALPHA_SET_FPMASK, &p);
-	}
-	__excb();
-	return (0);
-}
-
-int
-fesetenv(const fenv_t *envp)
-{
-	struct mask_args p;
-	union __fpcr r;
-
-	p.mask = *envp & FE_ALL_EXCEPT;
-	sysarch(ALPHA_SET_FPMASK, &p);
-	r.__bits = *envp & ~FE_ALL_EXCEPT;
-	__mt_fpcr(r.__d);
-	__excb();
-	return (0);
-}
-
-int
-feupdateenv(const fenv_t *envp)
-{
-	struct mask_args p;
-	union __fpcr oldr, newr;
-
-	p.mask = *envp & FE_ALL_EXCEPT;
-	sysarch(ALPHA_SET_FPMASK, &p);
-	__mf_fpcr(&oldr.__d);
-	newr.__bits = *envp & ~FE_ALL_EXCEPT;
-	__excb();
-	__mt_fpcr(newr.__d);
-	feraiseexcept((oldr.__bits >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
-	return (0); 
-}
-
-int
-__feenableexcept(int mask)
-{
-	struct mask_args p;
-
-	sysarch(ALPHA_GET_FPMASK, &p);
-	p.mask |= (mask & FE_ALL_EXCEPT);
-	sysarch(ALPHA_SET_FPMASK, &p);
-	return (p.mask);
-}
-
-int
-__fedisableexcept(int mask)
-{
-	struct mask_args p;
-
-	sysarch(ALPHA_GET_FPMASK, &p);
-	p.mask &= ~(mask & FE_ALL_EXCEPT);
-	sysarch(ALPHA_SET_FPMASK, &p);
-	return (p.mask);
-}
-
-int
-__fegetexcept(void)
-{
-	struct mask_args p;
-
-	sysarch(ALPHA_GET_FPMASK, &p);
-	return (p.mask);
-}
-
-__weak_reference(__feenableexcept, feenableexcept);
-__weak_reference(__fedisableexcept, fedisableexcept);
-__weak_reference(__fegetexcept, fegetexcept);
diff --git a/libm/alpha/fenv.h b/libm/alpha/fenv.h
deleted file mode 100644
index dc7bcb7..0000000
--- a/libm/alpha/fenv.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/alpha/fenv.h,v 1.3 2005/03/16 19:03:44 das Exp $
- */
-
-#ifndef	_FENV_H_
-#define	_FENV_H_
-
-#include <sys/_types.h>
-
-typedef	__uint64_t	fenv_t;
-typedef	__uint16_t	fexcept_t;
-
-/* Exception flags */
-#define	FE_INVALID	0x02
-#define	FE_DIVBYZERO	0x04
-#define	FE_OVERFLOW	0x08
-#define	FE_UNDERFLOW	0x10
-#define	FE_INEXACT	0x20
-#define	FE_INTOVF	0x40	/* not maskable */
-#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_INEXACT | FE_INTOVF | \
-			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
-
-/* Rounding modes */
-#define	FE_TOWARDZERO	0x00
-#define	FE_DOWNWARD	0x01
-#define	FE_TONEAREST	0x02
-#define	FE_UPWARD	0x03
-#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
-			 FE_UPWARD | FE_TOWARDZERO)
-#define	_ROUND_SHIFT	58
-
-#define	_FPUSW_SHIFT	51
-
-#define	__excb()	__asm __volatile("excb")
-#define	__mf_fpcr(__cw)	__asm __volatile("mf_fpcr %0" : "=f" (*(__cw)))
-#define	__mt_fpcr(__cw)	__asm __volatile("mt_fpcr %0" : : "f" (__cw))
-
-union __fpcr {
-	double __d;
-	fenv_t __bits;
-};
-
-__BEGIN_DECLS
-
-/* Default floating-point environment */
-extern const fenv_t	__fe_dfl_env;
-#define	FE_DFL_ENV	(&__fe_dfl_env)
-
-static __inline int
-feclearexcept(int __excepts)
-{
-	union __fpcr __r;
-
-	__excb();
-	__mf_fpcr(&__r.__d);
-	__r.__bits &= ~((fenv_t)__excepts << _FPUSW_SHIFT);
-	__mt_fpcr(__r.__d);
-	__excb();
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	union __fpcr __r;
-
-	__excb();
-	__mf_fpcr(&__r.__d);
-	__excb();
-	*__flagp = (__r.__bits >> _FPUSW_SHIFT) & __excepts;
-	return (0);
-}
-
-static __inline int
-fesetexceptflag(const fexcept_t *__flagp, int __excepts)
-{
-	union __fpcr __r;
-	fenv_t __xflag, __xexcepts;
-
-	__xflag = (fenv_t)*__flagp << _FPUSW_SHIFT;
-	__xexcepts = (fenv_t)__excepts << _FPUSW_SHIFT;
-	__excb();
-	__mf_fpcr(&__r.__d);
-	__r.__bits &= ~__xexcepts;
-	__r.__bits |= __xflag & __xexcepts;
-	__mt_fpcr(__r.__d);
-	__excb();
-	return (0);
-}
-
-static __inline int
-feraiseexcept(int __excepts)
-{
-
-	/*
-	 * XXX Generating exceptions this way does not actually invoke
-	 * a userland trap handler when enabled, but neither do
-	 * arithmetic operations as far as I can tell.  Perhaps there
-	 * are more bugs in the kernel trap handler.
-	 */
-	fexcept_t __ex = __excepts;
-	fesetexceptflag(&__ex, __excepts);
-	return (0);
-}
-
-static __inline int
-fetestexcept(int __excepts)
-{
-	union __fpcr __r;
-
-	__excb();
-	__mf_fpcr(&__r.__d);
-	__excb();
-	return ((__r.__bits >> _FPUSW_SHIFT) & __excepts);
-}
-
-static __inline int
-fegetround(void)
-{
-	union __fpcr __r;
-
-	/*
-	 * No exception barriers should be required here if we assume
-	 * that only fesetround() can change the rounding mode.
-	 */
-	__mf_fpcr(&__r.__d);
-	return ((int)(__r.__bits >> _ROUND_SHIFT) & _ROUND_MASK);
-}
-
-static __inline int
-fesetround(int __round)
-{
-	union __fpcr __r;
-
-	if (__round & ~_ROUND_MASK)
-		return (-1);
-	__excb();
-	__mf_fpcr(&__r.__d);
-	__r.__bits &= ~((fenv_t)_ROUND_MASK << _ROUND_SHIFT);
-	__r.__bits |= (fenv_t)__round << _ROUND_SHIFT;
-	__mt_fpcr(__r.__d);
-	__excb();
-	return (0);
-}
-
-int	fegetenv(fenv_t *__envp);
-int	feholdexcept(fenv_t *__envp);
-int	fesetenv(const fenv_t *__envp);
-int	feupdateenv(const fenv_t *__envp);
-
-#if __BSD_VISIBLE
-
-int	feenableexcept(int __mask);
-int	fedisableexcept(int __mask);
-int	fegetexcept(void);
-
-#endif /* __BSD_VISIBLE */
-
-__END_DECLS
-
-#endif	/* !_FENV_H_ */
diff --git a/libm/alpha/s_copysign.S b/libm/alpha/s_copysign.S
deleted file mode 100644
index 12381bb..0000000
--- a/libm/alpha/s_copysign.S
+++ /dev/null
@@ -1,45 +0,0 @@
-/* $FreeBSD: src/lib/msun/alpha/s_copysign.S,v 1.2 1999/08/28 00:06:07 peter Exp $ */
-/*	From: NetBSD: s_copysign.S,v 1.3 1997/07/30 23:58:38 jtc Exp	*/
-
-/*-
- * Copyright (c) 1996 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by J.T. Conklin.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-
-LEAF(copysign, 2)
-	cpys	fa1, fa0, fv0
-	RET
-END(copysign)
diff --git a/libm/alpha/s_copysignf.S b/libm/alpha/s_copysignf.S
deleted file mode 100644
index 2e5eda1..0000000
--- a/libm/alpha/s_copysignf.S
+++ /dev/null
@@ -1,45 +0,0 @@
-/* $FreeBSD: src/lib/msun/alpha/s_copysignf.S,v 1.2 1999/08/28 00:06:08 peter Exp $ */
-/*	From: NetBSD: s_copysignf.S,v 1.3 1997/07/30 23:58:41 jtc Exp */
-
-/*-
- * Copyright (c) 1996 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by J.T. Conklin.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-
-LEAF(copysignf, 2)
-	cpys	fa1, fa0, fv0
-	RET
-END(copysignf)
diff --git a/libm/amd64/Makefile.inc b/libm/amd64/Makefile.inc
deleted file mode 100644
index 43da775..0000000
--- a/libm/amd64/Makefile.inc
+++ /dev/null
@@ -1,5 +0,0 @@
-# $FreeBSD: src/lib/msun/amd64/Makefile.inc,v 1.4 2005/04/16 21:12:55 das Exp $
-
-ARCH_SRCS = e_sqrt.S e_sqrtf.S s_llrint.S s_llrintf.S s_lrint.S s_lrintf.S \
-	    s_remquo.S s_remquof.S s_scalbn.S s_scalbnf.S s_scalbnl.S
-LDBL_PREC = 64
diff --git a/libm/amd64/_fpmath.h b/libm/amd64/_fpmath.h
deleted file mode 100644
index 801ec80..0000000
--- a/libm/amd64/_fpmath.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*-
- * Copyright (c) 2002, 2003 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libc/amd64/_fpmath.h,v 1.6 2005/03/07 04:55:21 das Exp $
- */
-
-union IEEEl2bits {
-	long double	e;
-	struct {
-		unsigned int	manl	:32;
-		unsigned int	manh	:32;
-		unsigned int	exp	:15;
-		unsigned int	sign	:1;
-		unsigned int	junkl	:16;
-		unsigned int	junkh	:32;
-	} bits;
-};
-
-#define	LDBL_NBIT	0x80000000
-#define	mask_nbit_l(u)	((u).bits.manh &= ~LDBL_NBIT)
-
-#define	LDBL_MANH_SIZE	32
-#define	LDBL_MANL_SIZE	32
-
-#define	LDBL_TO_ARRAY32(u, a) do {			\
-	(a)[0] = (uint32_t)(u).bits.manl;		\
-	(a)[1] = (uint32_t)(u).bits.manh;		\
-} while(0)
diff --git a/libm/amd64/e_sqrt.S b/libm/amd64/e_sqrt.S
deleted file mode 100644
index 0429cce..0000000
--- a/libm/amd64/e_sqrt.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/amd64/e_sqrt.S,v 1.2 2005/02/04 14:08:32 das Exp $")
-	
-ENTRY(sqrt)
-	sqrtsd	%xmm0, %xmm0
-	ret
-
diff --git a/libm/amd64/e_sqrtf.S b/libm/amd64/e_sqrtf.S
deleted file mode 100644
index 471fa66..0000000
--- a/libm/amd64/e_sqrtf.S
+++ /dev/null
@@ -1,32 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/amd64/e_sqrtf.S,v 1.1 2005/04/16 21:12:55 das Exp $")
-	
-ENTRY(sqrtf)
-	sqrtss	%xmm0, %xmm0
-	ret
diff --git a/libm/amd64/fenv.c b/libm/amd64/fenv.c
deleted file mode 100644
index 2b43678..0000000
--- a/libm/amd64/fenv.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/amd64/fenv.c,v 1.3 2005/03/16 19:03:45 das Exp $
- */
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <machine/fpu.h>
-#include <fenv.h>
-
-const fenv_t __fe_dfl_env = {
-	{ 0xffff0000 | __INITIAL_FPUCW__,
-	  0xffff0000,
-	  0xffffffff,
-	  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff }
-	},
-	__INITIAL_MXCSR__
-};
-
-int
-fesetexceptflag(const fexcept_t *flagp, int excepts)
-{
-	fenv_t env;
-
-	__fnstenv(&env.__x87);
-	env.__x87.__status &= ~excepts;
-	env.__x87.__status |= *flagp & excepts;
-	__fldenv(env.__x87);
-
-	__stmxcsr(&env.__mxcsr);
-	env.__mxcsr &= ~excepts;
-	env.__mxcsr |= *flagp & excepts;
-	__ldmxcsr(env.__mxcsr);
-
-	return (0);
-}
-
-int
-feraiseexcept(int excepts)
-{
-	fexcept_t ex = excepts;
-
-	fesetexceptflag(&ex, excepts);
-	__fwait();
-	return (0);
-}
-
-int
-fegetenv(fenv_t *envp)
-{
-	int control;
-
-	/*
-	 * fnstenv masks all exceptions, so we need to save and
-	 * restore the control word to avoid this side effect.
-	 */
-	__fnstcw(&control);
-	__fnstenv(&envp->__x87);
-	__stmxcsr(&envp->__mxcsr);
-	__fldcw(control);
-	return (0);
-}
-
-int
-feholdexcept(fenv_t *envp)
-{
-	int mxcsr;
-
-	__stmxcsr(&mxcsr);
-	__fnstenv(&envp->__x87);
-	__fnclex();
-	envp->__mxcsr = mxcsr;
-	mxcsr &= ~FE_ALL_EXCEPT;
-	mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT;
-	__ldmxcsr(mxcsr);
-	return (0);
-}
-
-int
-feupdateenv(const fenv_t *envp)
-{
-	int mxcsr, status;
-
-	__fnstsw(&status);
-	__stmxcsr(&mxcsr);
-	fesetenv(envp);
-	feraiseexcept((mxcsr | status) & FE_ALL_EXCEPT);
-	return (0);
-}
-
-int
-__feenableexcept(int mask)
-{
-	int mxcsr, control, omask;
-
-	mask &= FE_ALL_EXCEPT;
-	__fnstcw(&control);
-	__stmxcsr(&mxcsr);
-	omask = (control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
-	control &= ~mask;
-	__fldcw(control);
-	mxcsr &= ~(mask << _SSE_EMASK_SHIFT);
-	__ldmxcsr(mxcsr);
-	return (~omask);
-}
-
-int
-__fedisableexcept(int mask)
-{
-	int mxcsr, control, omask;
-
-	mask &= FE_ALL_EXCEPT;
-	__fnstcw(&control);
-	__stmxcsr(&mxcsr);
-	omask = (control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
-	control |= mask;
-	__fldcw(control);
-	mxcsr |= mask << _SSE_EMASK_SHIFT;
-	__ldmxcsr(mxcsr);
-	return (~omask);
-}
-
-__weak_reference(__feenableexcept, feenableexcept);
-__weak_reference(__fedisableexcept, fedisableexcept);
diff --git a/libm/amd64/fenv.h b/libm/amd64/fenv.h
deleted file mode 100644
index c4f9432..0000000
--- a/libm/amd64/fenv.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/amd64/fenv.h,v 1.5 2005/03/16 22:34:14 das Exp $
- */
-
-#ifndef	_FENV_H_
-#define	_FENV_H_
-
-#include <sys/cdefs.h>
-#include <sys/_types.h>
-
-typedef struct {
-	struct {
-		__uint32_t	__control;
-		__uint32_t	__status;
-		__uint32_t	__tag;
-		char		__other[16];
-	} __x87;
-	__uint32_t		__mxcsr;
-} fenv_t;
-
-typedef	__uint16_t	fexcept_t;
-
-/* Exception flags */
-#define	FE_INVALID	0x01
-#define	FE_DENORMAL	0x02
-#define	FE_DIVBYZERO	0x04
-#define	FE_OVERFLOW	0x08
-#define	FE_UNDERFLOW	0x10
-#define	FE_INEXACT	0x20
-#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
-			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
-
-/* Rounding modes */
-#define	FE_TONEAREST	0x0000
-#define	FE_DOWNWARD	0x0400
-#define	FE_UPWARD	0x0800
-#define	FE_TOWARDZERO	0x0c00
-#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
-
-__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" : "=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)))
-
-static __inline int
-feclearexcept(int __excepts)
-{
-	fenv_t __env;
-
-	if (__excepts == FE_ALL_EXCEPT) {
-		__fnclex();
-	} else {
-		__fnstenv(&__env.__x87);
-		__env.__x87.__status &= ~__excepts;
-		__fldenv(__env.__x87);
-	}
-	__stmxcsr(&__env.__mxcsr);
-	__env.__mxcsr &= ~__excepts;
-	__ldmxcsr(__env.__mxcsr);
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	int __mxcsr, __status;
-
-	__stmxcsr(&__mxcsr);
-	__fnstsw(&__status);
-	*__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, __status;
-
-	__stmxcsr(&__mxcsr);
-	__fnstsw(&__status);
-	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);
-
-	__stmxcsr(&__mxcsr);
-	__mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
-	__mxcsr |= __round << _SSE_ROUND_SHIFT;
-	__ldmxcsr(__mxcsr);
-
-	return (0);
-}
-
-int fegetenv(fenv_t *__envp);
-int feholdexcept(fenv_t *__envp);
-
-static __inline int
-fesetenv(const fenv_t *__envp)
-{
-
-	__fldenv(__envp->__x87);
-	__ldmxcsr(__envp->__mxcsr);
-	return (0);
-}
-
-int feupdateenv(const fenv_t *__envp);
-
-#if __BSD_VISIBLE
-
-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);
-}
-
-#endif /* __BSD_VISIBLE */
-
-__END_DECLS
-
-#endif	/* !_FENV_H_ */
diff --git a/libm/amd64/s_llrint.S b/libm/amd64/s_llrint.S
deleted file mode 100644
index b81c73a..0000000
--- a/libm/amd64/s_llrint.S
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/amd64/s_llrint.S,v 1.1 2005/01/15 03:32:28 das Exp $")
-	
-/* sizeof(long) == sizeof(long long) */
-#define	fn	llrint
-#include "s_lrint.S"
diff --git a/libm/amd64/s_llrintf.S b/libm/amd64/s_llrintf.S
deleted file mode 100644
index d62cfcb..0000000
--- a/libm/amd64/s_llrintf.S
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/amd64/s_llrintf.S,v 1.1 2005/04/16 21:12:55 das Exp $")
-	
-/* sizeof(long) == sizeof(long long) */
-#define	fn	llrintf
-#include "s_lrintf.S"
diff --git a/libm/amd64/s_lrint.S b/libm/amd64/s_lrint.S
deleted file mode 100644
index 161b731..0000000
--- a/libm/amd64/s_lrint.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-
-#ifndef fn
-__FBSDID("$FreeBSD: src/lib/msun/amd64/s_lrint.S,v 1.1 2005/01/15 03:32:28 das Exp $")
-#define	fn	lrint
-#endif
-
-ENTRY(fn)
-	cvtsd2si %xmm0, %rax
-	ret
diff --git a/libm/amd64/s_lrintf.S b/libm/amd64/s_lrintf.S
deleted file mode 100644
index 506e834..0000000
--- a/libm/amd64/s_lrintf.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-
-#ifndef fn
-__FBSDID("$FreeBSD: src/lib/msun/amd64/s_lrintf.S,v 1.1 2005/04/16 21:12:55 das Exp $")
-#define	fn	lrintf
-#endif
-
-ENTRY(fn)
-	cvtss2si %xmm0, %rax
-	ret
diff --git a/libm/amd64/s_remquo.S b/libm/amd64/s_remquo.S
deleted file mode 100644
index 19f3b53..0000000
--- a/libm/amd64/s_remquo.S
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Based on public-domain remainder routine by J.T. Conklin <jtc@NetBSD.org>.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/amd64/s_remquo.S,v 1.1 2005/03/25 04:40:44 das Exp $"); 
-	
-ENTRY(remquo)
-	movsd	%xmm0,-8(%rsp)
-	movsd	%xmm1,-16(%rsp)
-	fldl	-16(%rsp)
-	fldl	-8(%rsp)
-1:	fprem1
-	fstsw	%ax
-	btw	$10,%ax
-	jc	1b
-	fstp	%st(1)
-/* Extract the three low-order bits of the quotient from C0,C3,C1. */
-	shrl	$6,%eax
-	movl	%eax,%ecx
-	andl	$0x108,%eax
-	rorl	$7,%eax
-	orl	%eax,%ecx
-	roll	$4,%eax
-	orl	%ecx,%eax
-	andl	$7,%eax
-/* Negate the quotient bits if x*y<0.  Avoid using an unpredictable branch. */
-	movl	-12(%rsp),%ecx
-	xorl	-4(%rsp),%ecx
-	sarl	$16,%ecx
-	sarl	$16,%ecx
-	xorl	%ecx,%eax
-	andl	$1,%ecx
-	addl	%ecx,%eax
-/* Store the quotient and return. */
-	movl	%eax,(%rdi)
-	fstpl	-8(%rsp)
-	movsd	-8(%rsp),%xmm0
-	ret
diff --git a/libm/amd64/s_remquof.S b/libm/amd64/s_remquof.S
deleted file mode 100644
index 02b604f..0000000
--- a/libm/amd64/s_remquof.S
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Based on public-domain remainder routine by J.T. Conklin <jtc@NetBSD.org>.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/amd64/s_remquof.S,v 1.1 2005/03/25 04:40:44 das Exp $"); 
-	
-ENTRY(remquof)
-	movss	%xmm0,-4(%rsp)
-	movss	%xmm1,-8(%rsp)
-	flds	-8(%rsp)
-	flds	-4(%rsp)
-1:	fprem1
-	fstsw	%ax
-	btw	$10,%ax
-	jc	1b
-	fstp	%st(1)
-/* Extract the three low-order bits of the quotient from C0,C3,C1. */
-	shrl	$6,%eax
-	movl	%eax,%ecx
-	andl	$0x108,%eax
-	rorl	$7,%eax
-	orl	%eax,%ecx
-	roll	$4,%eax
-	orl	%ecx,%eax
-	andl	$7,%eax
-/* Negate the quotient bits if x*y<0.  Avoid using an unpredictable branch. */
-	movl	-8(%rsp),%ecx
-	xorl	-4(%rsp),%ecx
-	sarl	$16,%ecx
-	sarl	$16,%ecx
-	xorl	%ecx,%eax
-	andl	$1,%ecx
-	addl	%ecx,%eax
-/* Store the quotient and return. */
-	movl	%eax,(%rdi)
-	fstps	-4(%rsp)
-	movss	-4(%rsp),%xmm0
-	ret
diff --git a/libm/amd64/s_scalbn.S b/libm/amd64/s_scalbn.S
deleted file mode 100644
index 6942e18..0000000
--- a/libm/amd64/s_scalbn.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/amd64/s_scalbn.S,v 1.1 2005/04/16 21:12:55 das Exp $")
-
-ENTRY(scalbn)
-	movsd	%xmm0,-8(%rsp)
-	movl	%edi,-12(%rsp)
-	fildl	-12(%rsp)
-	fldl	-8(%rsp)
-	fscale
-	fstp	%st(1)
-	fstpl	-8(%rsp)
-	movsd	-8(%rsp),%xmm0
-	ret
diff --git a/libm/amd64/s_scalbnf.S b/libm/amd64/s_scalbnf.S
deleted file mode 100644
index d7b9ab7..0000000
--- a/libm/amd64/s_scalbnf.S
+++ /dev/null
@@ -1,42 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/amd64/s_scalbnf.S,v 1.2 2005/09/12 20:54:00 das Exp $")
-
-ENTRY(scalbnf)
-	movss	%xmm0,-8(%rsp)
-	movl	%edi,-4(%rsp)
-	fildl	-4(%rsp)
-	flds	-8(%rsp)
-	fscale
-	fstp	%st(1)
-	fstps	-8(%rsp)
-	movss	-8(%rsp),%xmm0
-	ret
-
-.globl CNAME(ldexpf)
-.set	CNAME(ldexpf),CNAME(scalbnf)
diff --git a/libm/amd64/s_scalbnl.S b/libm/amd64/s_scalbnl.S
deleted file mode 100644
index 57629a4..0000000
--- a/libm/amd64/s_scalbnl.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Based on code written by J.T. Conklin <jtc@netbsd.org>.
- * Public domain.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/amd64/s_scalbnl.S,v 1.1 2005/04/16 21:12:55 das Exp $")
-/* RCSID("$NetBSD: s_scalbnf.S,v 1.4 1999/01/02 05:15:40 kristerw Exp $") */
-
-ENTRY(scalbnl)
-	movl	%edi,-4(%rsp)
-	fildl	-4(%rsp)
-	fldt	8(%rsp)
-	fscale
-	fstp	%st(1)
-	ret
-
-.globl	CNAME(ldexpl)
-.set	CNAME(ldexpl),CNAME(scalbnl)
diff --git a/libm/arm/Makefile.inc b/libm/arm/Makefile.inc
deleted file mode 100644
index 6559cc3..0000000
--- a/libm/arm/Makefile.inc
+++ /dev/null
@@ -1,3 +0,0 @@
-# $FreeBSD: src/lib/msun/arm/Makefile.inc,v 1.1 2005/03/07 04:53:35 das Exp $
-
-LDBL_PREC = 53
diff --git a/libm/i387/Makefile.inc b/libm/i387/Makefile.inc
deleted file mode 100644
index d83a56b..0000000
--- a/libm/i387/Makefile.inc
+++ /dev/null
@@ -1,18 +0,0 @@
-# $FreeBSD: src/lib/msun/i387/Makefile.inc,v 1.7 2005/04/16 21:12:55 das Exp $
-
-ARCH_SRCS = e_exp.S e_fmod.S e_log.S e_log10.S \
-	    e_remainder.S e_scalb.S e_sqrt.S s_ceil.S s_copysign.S \
-	    s_cos.S s_finite.S s_floor.S s_llrint.S s_logb.S s_lrint.S \
-	    s_remquo.S s_rint.S s_scalbn.S s_significand.S s_sin.S s_tan.S \
-	    s_trunc.S
-
-# float counterparts
-ARCH_SRCS+= e_log10f.S e_logf.S e_remainderf.S e_scalbf.S \
-	    e_sqrtf.S s_ceilf.S s_copysignf.S s_floorf.S \
-	    s_llrintf.S s_logbf.S s_lrintf.S \
-	    s_remquof.S s_rintf.S s_scalbnf.S s_significandf.S s_truncf.S
-
-# long double counterparts
-ARCH_SRCS+= s_ceill.S s_copysignl.S s_floorl.S s_scalbnl.S s_truncl.S
-
-LDBL_PREC = 64	# XXX 64-bit format, but truncated to 53 bits
diff --git a/libm/ia64/Makefile.inc b/libm/ia64/Makefile.inc
deleted file mode 100644
index fdf2267..0000000
--- a/libm/ia64/Makefile.inc
+++ /dev/null
@@ -1,4 +0,0 @@
-# $FreeBSD: src/lib/msun/ia64/Makefile.inc,v 1.2 2005/03/07 04:54:02 das Exp $
-
-ARCH_SRCS = s_fma.S s_fmaf.S s_fmal.S
-LDBL_PREC = 64
diff --git a/libm/ia64/_fpmath.h b/libm/ia64/_fpmath.h
deleted file mode 100644
index b0e75ed..0000000
--- a/libm/ia64/_fpmath.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
- * Copyright (c) 2002, 2003 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libc/ia64/_fpmath.h,v 1.6 2005/03/07 04:55:40 das Exp $
- */
-
-#include <sys/endian.h>
-
-union IEEEl2bits {
-	long double	e;
-	struct {
-#if _BYTE_ORDER == _LITTLE_ENDIAN
-		unsigned int	manl	:32;
-		unsigned int	manh	:32;
-		unsigned int	exp	:15;
-		unsigned int	sign	:1;
-		unsigned long	junk	:48;
-#else /* _BIG_ENDIAN */
-		unsigned long	junk	:48;
-		unsigned int	sign	:1;
-		unsigned int	exp	:15;
-		unsigned int	manh	:32;
-		unsigned int	manl	:32;
-#endif
-	} bits;
-};
-
-#if _BYTE_ORDER == _LITTLE_ENDIAN
-#define	LDBL_NBIT	0x80000000
-#define	mask_nbit_l(u)	((u).bits.manh &= ~LDBL_NBIT)
-#else /* _BIG_ENDIAN */
-/*
- * XXX This doesn't look right.  Very few machines have a different
- *     endianness for integers and floating-point, and in nextafterl()
- *     we assume that none do.  If you have an environment for testing
- *     this, please let me know. --das
- */
-#define	LDBL_NBIT	0x80
-#define	mask_nbit_l(u)	((u).bits.manh &= ~LDBL_NBIT)
-#endif
-
-#define	LDBL_MANH_SIZE	32
-#define	LDBL_MANL_SIZE	32
-
-#define	LDBL_TO_ARRAY32(u, a) do {			\
-	(a)[0] = (uint32_t)(u).bits.manl;		\
-	(a)[1] = (uint32_t)(u).bits.manh;		\
-} while(0)
diff --git a/libm/ia64/fenv.c b/libm/ia64/fenv.c
deleted file mode 100644
index 182d37e..0000000
--- a/libm/ia64/fenv.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-
- * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/ia64/fenv.c,v 1.2 2004/06/11 02:35:30 das Exp $
- */
-
-#include <sys/types.h>
-#include <fenv.h>
-
-const fenv_t __fe_dfl_env = 0x0009804c8a70033fULL;
-
-/*
- * It doesn't pay to inline feupdateenv() because it includes one of
- * the rare uses of feraiseexcept() where the argument is not a
- * constant.  Thus, no dead code elimination can occur, resulting in
- * significant bloat.
- */
-int
-feupdateenv(const fenv_t *envp)
-{
-	fenv_t fpsr;
-
-	__stfpsr(&fpsr);
-	__ldfpsr(*envp);
-	feraiseexcept((fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
-	return (0);
-}
diff --git a/libm/ia64/fenv.h b/libm/ia64/fenv.h
deleted file mode 100644
index 8c6b65b..0000000
--- a/libm/ia64/fenv.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/ia64/fenv.h,v 1.4 2005/03/16 19:03:45 das Exp $
- */
-
-#ifndef	_FENV_H_
-#define	_FENV_H_
-
-#include <sys/_types.h>
-
-typedef	__uint64_t	fenv_t;
-typedef	__uint16_t	fexcept_t;
-
-/* Exception flags */
-#define	FE_INVALID	0x01
-#define	FE_DENORMAL	0x02
-#define	FE_DIVBYZERO	0x04
-#define	FE_OVERFLOW	0x08
-#define	FE_UNDERFLOW	0x10
-#define	FE_INEXACT	0x20
-#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
-			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
-
-/* Rounding modes */
-#define	FE_TONEAREST	0x0000
-#define	FE_DOWNWARD	0x0400
-#define	FE_UPWARD	0x0800
-#define	FE_TOWARDZERO	0x0c00
-#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
-			 FE_UPWARD | FE_TOWARDZERO)
-
-__BEGIN_DECLS
-
-/* Default floating-point environment */
-extern const fenv_t	__fe_dfl_env;
-#define	FE_DFL_ENV	(&__fe_dfl_env)
-
-#define	_FPUSW_SHIFT	13
-
-#define	__stfpsr(__r)	__asm __volatile("mov %0=ar.fpsr" : "=r" (*(__r)))
-#define	__ldfpsr(__r)	__asm __volatile("mov ar.fpsr=%0;;" : : "r" (__r))
-
-static __inline int
-feclearexcept(int __excepts)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	__fpsr &= ~((fenv_t)__excepts << _FPUSW_SHIFT);
-	__ldfpsr(__fpsr);
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	*__flagp = (fexcept_t)(__fpsr >> _FPUSW_SHIFT) & __excepts;
-	return (0);
-}
-
-static __inline int
-fesetexceptflag(const fexcept_t *__flagp, int __excepts)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	__fpsr &= ~((fenv_t)__excepts << _FPUSW_SHIFT);
-	__fpsr |= (fenv_t)(__excepts & *__flagp) << _FPUSW_SHIFT;
-	__ldfpsr(__fpsr);
-	return (0);
-}
-
-/*
- * It is worthwhile to use the inline version of this function iff it
- * is called with arguments that are compile-time constants (due to
- * dead code elimination).  Unfortunately, gcc isn't smart enough to
- * figure this out automatically, and there's no way to tell it.
- * We assume that constant arguments will be the common case.
- */
-static __inline int
-feraiseexcept(int __excepts)
-{
-	volatile double d;
-
-	/*
-	 * With a compiler that supports the FENV_ACCESS pragma
-	 * properly, simple expressions like '0.0 / 0.0' should
-	 * be sufficient to generate traps.  Unfortunately, we
-	 * need to bring a volatile variable into the equation
-	 * to prevent incorrect optimizations.
-	 */
-	if (__excepts & FE_INVALID) {
-		d = 0.0;
-		d = 0.0 / d;
-	}
-	if (__excepts & FE_DIVBYZERO) {
-		d = 0.0;
-		d = 1.0 / d;
-	}
-	if (__excepts & FE_OVERFLOW) {
-		d = 0x1.ffp1023;
-		d *= 2.0;
-	}
-	if (__excepts & FE_UNDERFLOW) {
-		d = 0x1p-1022;
-		d /= 0x1p1023;
-	}
-	if (__excepts & FE_INEXACT) {
-		d = 0x1p-1022;
-		d += 1.0;
-	}
-	return (0);
-}
-
-static __inline int
-fetestexcept(int __excepts)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	return ((__fpsr >> _FPUSW_SHIFT) & __excepts);
-}
-
-
-static __inline int
-fegetround(void)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	return (__fpsr & _ROUND_MASK);
-}
-
-static __inline int
-fesetround(int __round)
-{
-	fenv_t __fpsr;
-
-	if (__round & ~_ROUND_MASK)
-		return (-1);
-	__stfpsr(&__fpsr);
-	__fpsr &= ~_ROUND_MASK;
-	__fpsr |= __round;
-	__ldfpsr(__fpsr);
-	return (0);
-}
-
-static __inline int
-fegetenv(fenv_t *__envp)
-{
-
-	__stfpsr(__envp);
-	return (0);
-}
-
-static __inline int
-feholdexcept(fenv_t *__envp)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	*__envp = __fpsr;
-	__fpsr &= ~((fenv_t)FE_ALL_EXCEPT << _FPUSW_SHIFT);
-	__fpsr |= FE_ALL_EXCEPT;
-	__ldfpsr(__fpsr);
-	return (0);
-}
-
-static __inline int
-fesetenv(const fenv_t *__envp)
-{
-
-	__ldfpsr(*__envp);
-	return (0);
-}
-
-int feupdateenv(const fenv_t *__envp);
-
-#if __BSD_VISIBLE
-
-static __inline int
-feenableexcept(int __mask)
-{
-	fenv_t __newfpsr, __oldfpsr;
-
-	__stfpsr(&__oldfpsr);
-	__newfpsr = __oldfpsr & ~(__mask & FE_ALL_EXCEPT);
-	__ldfpsr(__newfpsr);
-	return (~__oldfpsr & FE_ALL_EXCEPT);
-}
-
-static __inline int
-fedisableexcept(int __mask)
-{
-	fenv_t __newfpsr, __oldfpsr;
-
-	__stfpsr(&__oldfpsr);
-	__newfpsr = __oldfpsr | (__mask & FE_ALL_EXCEPT);
-	__ldfpsr(__newfpsr);
-	return (~__oldfpsr & FE_ALL_EXCEPT);
-}
-
-static __inline int
-fegetexcept(void)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	return (~__fpsr & FE_ALL_EXCEPT);
-}
-
-#endif /* __BSD_VISIBLE */
-
-__END_DECLS
-
-#endif	/* !_FENV_H_ */
diff --git a/libm/ia64/s_fma.S b/libm/ia64/s_fma.S
deleted file mode 100644
index 2da6c17..0000000
--- a/libm/ia64/s_fma.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/ia64/s_fma.S,v 1.1 2005/01/22 09:53:18 das Exp $")
-
-ENTRY(fma, 3)
-{
-	fma.d		f8 = f8, f9, f10
-	br.ret.sptk	b0
-}
diff --git a/libm/ia64/s_fmaf.S b/libm/ia64/s_fmaf.S
deleted file mode 100644
index 320051b..0000000
--- a/libm/ia64/s_fmaf.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/ia64/s_fmaf.S,v 1.1 2005/01/22 09:53:18 das Exp $")
-
-ENTRY(fmaf, 3)
-{
-	fma.s		f8 = f8, f9, f10
-	br.ret.sptk	b0
-}
diff --git a/libm/ia64/s_fmal.S b/libm/ia64/s_fmal.S
deleted file mode 100644
index 7b8c407..0000000
--- a/libm/ia64/s_fmal.S
+++ /dev/null
@@ -1,34 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/ia64/s_fmal.S,v 1.1 2005/03/07 04:53:11 das Exp $")
-
-ENTRY(fmal, 3)
-{
-	fma		f8 = f8, f9, f10
-	br.ret.sptk	b0
-}
diff --git a/libm/include/alpha/fenv.h b/libm/include/alpha/fenv.h
deleted file mode 100644
index dc7bcb7..0000000
--- a/libm/include/alpha/fenv.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/alpha/fenv.h,v 1.3 2005/03/16 19:03:44 das Exp $
- */
-
-#ifndef	_FENV_H_
-#define	_FENV_H_
-
-#include <sys/_types.h>
-
-typedef	__uint64_t	fenv_t;
-typedef	__uint16_t	fexcept_t;
-
-/* Exception flags */
-#define	FE_INVALID	0x02
-#define	FE_DIVBYZERO	0x04
-#define	FE_OVERFLOW	0x08
-#define	FE_UNDERFLOW	0x10
-#define	FE_INEXACT	0x20
-#define	FE_INTOVF	0x40	/* not maskable */
-#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_INEXACT | FE_INTOVF | \
-			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
-
-/* Rounding modes */
-#define	FE_TOWARDZERO	0x00
-#define	FE_DOWNWARD	0x01
-#define	FE_TONEAREST	0x02
-#define	FE_UPWARD	0x03
-#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
-			 FE_UPWARD | FE_TOWARDZERO)
-#define	_ROUND_SHIFT	58
-
-#define	_FPUSW_SHIFT	51
-
-#define	__excb()	__asm __volatile("excb")
-#define	__mf_fpcr(__cw)	__asm __volatile("mf_fpcr %0" : "=f" (*(__cw)))
-#define	__mt_fpcr(__cw)	__asm __volatile("mt_fpcr %0" : : "f" (__cw))
-
-union __fpcr {
-	double __d;
-	fenv_t __bits;
-};
-
-__BEGIN_DECLS
-
-/* Default floating-point environment */
-extern const fenv_t	__fe_dfl_env;
-#define	FE_DFL_ENV	(&__fe_dfl_env)
-
-static __inline int
-feclearexcept(int __excepts)
-{
-	union __fpcr __r;
-
-	__excb();
-	__mf_fpcr(&__r.__d);
-	__r.__bits &= ~((fenv_t)__excepts << _FPUSW_SHIFT);
-	__mt_fpcr(__r.__d);
-	__excb();
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	union __fpcr __r;
-
-	__excb();
-	__mf_fpcr(&__r.__d);
-	__excb();
-	*__flagp = (__r.__bits >> _FPUSW_SHIFT) & __excepts;
-	return (0);
-}
-
-static __inline int
-fesetexceptflag(const fexcept_t *__flagp, int __excepts)
-{
-	union __fpcr __r;
-	fenv_t __xflag, __xexcepts;
-
-	__xflag = (fenv_t)*__flagp << _FPUSW_SHIFT;
-	__xexcepts = (fenv_t)__excepts << _FPUSW_SHIFT;
-	__excb();
-	__mf_fpcr(&__r.__d);
-	__r.__bits &= ~__xexcepts;
-	__r.__bits |= __xflag & __xexcepts;
-	__mt_fpcr(__r.__d);
-	__excb();
-	return (0);
-}
-
-static __inline int
-feraiseexcept(int __excepts)
-{
-
-	/*
-	 * XXX Generating exceptions this way does not actually invoke
-	 * a userland trap handler when enabled, but neither do
-	 * arithmetic operations as far as I can tell.  Perhaps there
-	 * are more bugs in the kernel trap handler.
-	 */
-	fexcept_t __ex = __excepts;
-	fesetexceptflag(&__ex, __excepts);
-	return (0);
-}
-
-static __inline int
-fetestexcept(int __excepts)
-{
-	union __fpcr __r;
-
-	__excb();
-	__mf_fpcr(&__r.__d);
-	__excb();
-	return ((__r.__bits >> _FPUSW_SHIFT) & __excepts);
-}
-
-static __inline int
-fegetround(void)
-{
-	union __fpcr __r;
-
-	/*
-	 * No exception barriers should be required here if we assume
-	 * that only fesetround() can change the rounding mode.
-	 */
-	__mf_fpcr(&__r.__d);
-	return ((int)(__r.__bits >> _ROUND_SHIFT) & _ROUND_MASK);
-}
-
-static __inline int
-fesetround(int __round)
-{
-	union __fpcr __r;
-
-	if (__round & ~_ROUND_MASK)
-		return (-1);
-	__excb();
-	__mf_fpcr(&__r.__d);
-	__r.__bits &= ~((fenv_t)_ROUND_MASK << _ROUND_SHIFT);
-	__r.__bits |= (fenv_t)__round << _ROUND_SHIFT;
-	__mt_fpcr(__r.__d);
-	__excb();
-	return (0);
-}
-
-int	fegetenv(fenv_t *__envp);
-int	feholdexcept(fenv_t *__envp);
-int	fesetenv(const fenv_t *__envp);
-int	feupdateenv(const fenv_t *__envp);
-
-#if __BSD_VISIBLE
-
-int	feenableexcept(int __mask);
-int	fedisableexcept(int __mask);
-int	fegetexcept(void);
-
-#endif /* __BSD_VISIBLE */
-
-__END_DECLS
-
-#endif	/* !_FENV_H_ */
diff --git a/libm/include/amd64/fenv.h b/libm/include/amd64/fenv.h
deleted file mode 100644
index c4f9432..0000000
--- a/libm/include/amd64/fenv.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/amd64/fenv.h,v 1.5 2005/03/16 22:34:14 das Exp $
- */
-
-#ifndef	_FENV_H_
-#define	_FENV_H_
-
-#include <sys/cdefs.h>
-#include <sys/_types.h>
-
-typedef struct {
-	struct {
-		__uint32_t	__control;
-		__uint32_t	__status;
-		__uint32_t	__tag;
-		char		__other[16];
-	} __x87;
-	__uint32_t		__mxcsr;
-} fenv_t;
-
-typedef	__uint16_t	fexcept_t;
-
-/* Exception flags */
-#define	FE_INVALID	0x01
-#define	FE_DENORMAL	0x02
-#define	FE_DIVBYZERO	0x04
-#define	FE_OVERFLOW	0x08
-#define	FE_UNDERFLOW	0x10
-#define	FE_INEXACT	0x20
-#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
-			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
-
-/* Rounding modes */
-#define	FE_TONEAREST	0x0000
-#define	FE_DOWNWARD	0x0400
-#define	FE_UPWARD	0x0800
-#define	FE_TOWARDZERO	0x0c00
-#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
-
-__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" : "=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)))
-
-static __inline int
-feclearexcept(int __excepts)
-{
-	fenv_t __env;
-
-	if (__excepts == FE_ALL_EXCEPT) {
-		__fnclex();
-	} else {
-		__fnstenv(&__env.__x87);
-		__env.__x87.__status &= ~__excepts;
-		__fldenv(__env.__x87);
-	}
-	__stmxcsr(&__env.__mxcsr);
-	__env.__mxcsr &= ~__excepts;
-	__ldmxcsr(__env.__mxcsr);
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	int __mxcsr, __status;
-
-	__stmxcsr(&__mxcsr);
-	__fnstsw(&__status);
-	*__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, __status;
-
-	__stmxcsr(&__mxcsr);
-	__fnstsw(&__status);
-	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);
-
-	__stmxcsr(&__mxcsr);
-	__mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
-	__mxcsr |= __round << _SSE_ROUND_SHIFT;
-	__ldmxcsr(__mxcsr);
-
-	return (0);
-}
-
-int fegetenv(fenv_t *__envp);
-int feholdexcept(fenv_t *__envp);
-
-static __inline int
-fesetenv(const fenv_t *__envp)
-{
-
-	__fldenv(__envp->__x87);
-	__ldmxcsr(__envp->__mxcsr);
-	return (0);
-}
-
-int feupdateenv(const fenv_t *__envp);
-
-#if __BSD_VISIBLE
-
-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);
-}
-
-#endif /* __BSD_VISIBLE */
-
-__END_DECLS
-
-#endif	/* !_FENV_H_ */
diff --git a/libm/include/arm/fenv.h b/libm/include/arm/fenv.h
index e7a8860..da7e696 100644
--- a/libm/include/arm/fenv.h
+++ b/libm/include/arm/fenv.h
@@ -29,7 +29,9 @@
 #ifndef	_FENV_H_
 #define	_FENV_H_
 
-#include <sys/_types.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
 
 typedef	__uint32_t	fenv_t;
 typedef	__uint32_t	fexcept_t;
@@ -50,7 +52,6 @@
 #define	FE_DOWNWARD	0x0003
 #define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
 			 FE_UPWARD | FE_TOWARDZERO)
-__BEGIN_DECLS
 
 /* Default floating-point environment */
 extern const fenv_t	__fe_dfl_env;
diff --git a/libm/include/i387/fenv.h b/libm/include/i387/fenv.h
index 4e322b7..c0421c0 100644
--- a/libm/include/i387/fenv.h
+++ b/libm/include/i387/fenv.h
@@ -29,8 +29,7 @@
 #ifndef	_FENV_H_
 #define	_FENV_H_
 
-#include <sys/cdefs.h>
-#include <sys/_types.h>
+#include <sys/types.h>
 
 __BEGIN_DECLS
 
diff --git a/libm/include/ia64/fenv.h b/libm/include/ia64/fenv.h
deleted file mode 100644
index 8c6b65b..0000000
--- a/libm/include/ia64/fenv.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/ia64/fenv.h,v 1.4 2005/03/16 19:03:45 das Exp $
- */
-
-#ifndef	_FENV_H_
-#define	_FENV_H_
-
-#include <sys/_types.h>
-
-typedef	__uint64_t	fenv_t;
-typedef	__uint16_t	fexcept_t;
-
-/* Exception flags */
-#define	FE_INVALID	0x01
-#define	FE_DENORMAL	0x02
-#define	FE_DIVBYZERO	0x04
-#define	FE_OVERFLOW	0x08
-#define	FE_UNDERFLOW	0x10
-#define	FE_INEXACT	0x20
-#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
-			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
-
-/* Rounding modes */
-#define	FE_TONEAREST	0x0000
-#define	FE_DOWNWARD	0x0400
-#define	FE_UPWARD	0x0800
-#define	FE_TOWARDZERO	0x0c00
-#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
-			 FE_UPWARD | FE_TOWARDZERO)
-
-__BEGIN_DECLS
-
-/* Default floating-point environment */
-extern const fenv_t	__fe_dfl_env;
-#define	FE_DFL_ENV	(&__fe_dfl_env)
-
-#define	_FPUSW_SHIFT	13
-
-#define	__stfpsr(__r)	__asm __volatile("mov %0=ar.fpsr" : "=r" (*(__r)))
-#define	__ldfpsr(__r)	__asm __volatile("mov ar.fpsr=%0;;" : : "r" (__r))
-
-static __inline int
-feclearexcept(int __excepts)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	__fpsr &= ~((fenv_t)__excepts << _FPUSW_SHIFT);
-	__ldfpsr(__fpsr);
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	*__flagp = (fexcept_t)(__fpsr >> _FPUSW_SHIFT) & __excepts;
-	return (0);
-}
-
-static __inline int
-fesetexceptflag(const fexcept_t *__flagp, int __excepts)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	__fpsr &= ~((fenv_t)__excepts << _FPUSW_SHIFT);
-	__fpsr |= (fenv_t)(__excepts & *__flagp) << _FPUSW_SHIFT;
-	__ldfpsr(__fpsr);
-	return (0);
-}
-
-/*
- * It is worthwhile to use the inline version of this function iff it
- * is called with arguments that are compile-time constants (due to
- * dead code elimination).  Unfortunately, gcc isn't smart enough to
- * figure this out automatically, and there's no way to tell it.
- * We assume that constant arguments will be the common case.
- */
-static __inline int
-feraiseexcept(int __excepts)
-{
-	volatile double d;
-
-	/*
-	 * With a compiler that supports the FENV_ACCESS pragma
-	 * properly, simple expressions like '0.0 / 0.0' should
-	 * be sufficient to generate traps.  Unfortunately, we
-	 * need to bring a volatile variable into the equation
-	 * to prevent incorrect optimizations.
-	 */
-	if (__excepts & FE_INVALID) {
-		d = 0.0;
-		d = 0.0 / d;
-	}
-	if (__excepts & FE_DIVBYZERO) {
-		d = 0.0;
-		d = 1.0 / d;
-	}
-	if (__excepts & FE_OVERFLOW) {
-		d = 0x1.ffp1023;
-		d *= 2.0;
-	}
-	if (__excepts & FE_UNDERFLOW) {
-		d = 0x1p-1022;
-		d /= 0x1p1023;
-	}
-	if (__excepts & FE_INEXACT) {
-		d = 0x1p-1022;
-		d += 1.0;
-	}
-	return (0);
-}
-
-static __inline int
-fetestexcept(int __excepts)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	return ((__fpsr >> _FPUSW_SHIFT) & __excepts);
-}
-
-
-static __inline int
-fegetround(void)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	return (__fpsr & _ROUND_MASK);
-}
-
-static __inline int
-fesetround(int __round)
-{
-	fenv_t __fpsr;
-
-	if (__round & ~_ROUND_MASK)
-		return (-1);
-	__stfpsr(&__fpsr);
-	__fpsr &= ~_ROUND_MASK;
-	__fpsr |= __round;
-	__ldfpsr(__fpsr);
-	return (0);
-}
-
-static __inline int
-fegetenv(fenv_t *__envp)
-{
-
-	__stfpsr(__envp);
-	return (0);
-}
-
-static __inline int
-feholdexcept(fenv_t *__envp)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	*__envp = __fpsr;
-	__fpsr &= ~((fenv_t)FE_ALL_EXCEPT << _FPUSW_SHIFT);
-	__fpsr |= FE_ALL_EXCEPT;
-	__ldfpsr(__fpsr);
-	return (0);
-}
-
-static __inline int
-fesetenv(const fenv_t *__envp)
-{
-
-	__ldfpsr(*__envp);
-	return (0);
-}
-
-int feupdateenv(const fenv_t *__envp);
-
-#if __BSD_VISIBLE
-
-static __inline int
-feenableexcept(int __mask)
-{
-	fenv_t __newfpsr, __oldfpsr;
-
-	__stfpsr(&__oldfpsr);
-	__newfpsr = __oldfpsr & ~(__mask & FE_ALL_EXCEPT);
-	__ldfpsr(__newfpsr);
-	return (~__oldfpsr & FE_ALL_EXCEPT);
-}
-
-static __inline int
-fedisableexcept(int __mask)
-{
-	fenv_t __newfpsr, __oldfpsr;
-
-	__stfpsr(&__oldfpsr);
-	__newfpsr = __oldfpsr | (__mask & FE_ALL_EXCEPT);
-	__ldfpsr(__newfpsr);
-	return (~__oldfpsr & FE_ALL_EXCEPT);
-}
-
-static __inline int
-fegetexcept(void)
-{
-	fenv_t __fpsr;
-
-	__stfpsr(&__fpsr);
-	return (~__fpsr & FE_ALL_EXCEPT);
-}
-
-#endif /* __BSD_VISIBLE */
-
-__END_DECLS
-
-#endif	/* !_FENV_H_ */
diff --git a/libm/include/mips/fenv.h b/libm/include/mips/fenv.h
index e7a8860..da7e696 100644
--- a/libm/include/mips/fenv.h
+++ b/libm/include/mips/fenv.h
@@ -29,7 +29,9 @@
 #ifndef	_FENV_H_
 #define	_FENV_H_
 
-#include <sys/_types.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
 
 typedef	__uint32_t	fenv_t;
 typedef	__uint32_t	fexcept_t;
@@ -50,7 +52,6 @@
 #define	FE_DOWNWARD	0x0003
 #define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
 			 FE_UPWARD | FE_TOWARDZERO)
-__BEGIN_DECLS
 
 /* Default floating-point environment */
 extern const fenv_t	__fe_dfl_env;
diff --git a/libm/include/powerpc/fenv.h b/libm/include/powerpc/fenv.h
deleted file mode 100644
index 3fd2389..0000000
--- a/libm/include/powerpc/fenv.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/powerpc/fenv.h,v 1.3 2005/03/16 19:03:45 das Exp $
- */
-
-#ifndef	_FENV_H_
-#define	_FENV_H_
-
-#include <sys/_types.h>
-
-typedef	__uint32_t	fenv_t;
-typedef	__uint32_t	fexcept_t;
-
-/* Exception flags */
-#define	FE_INEXACT	0x02000000
-#define	FE_DIVBYZERO	0x04000000
-#define	FE_UNDERFLOW	0x08000000
-#define	FE_OVERFLOW	0x10000000
-#define	FE_INVALID	0x20000000	/* all types of invalid FP ops */
-
-/*
- * The PowerPC architecture has extra invalid flags that indicate the
- * specific type of invalid operation occurred.  These flags may be
- * tested, set, and cleared---but not masked---separately.  All of
- * these bits are cleared when FE_INVALID is cleared, but only
- * FE_VXSOFT is set when FE_INVALID is explicitly set in software.
- */
-#define	FE_VXCVI	0x00000100	/* invalid integer convert */
-#define	FE_VXSQRT	0x00000200	/* square root of a negative */
-#define	FE_VXSOFT	0x00000400	/* software-requested exception */
-#define	FE_VXVC		0x00080000	/* ordered comparison involving NaN */
-#define	FE_VXIMZ	0x00100000	/* inf * 0 */
-#define	FE_VXZDZ	0x00200000	/* 0 / 0 */
-#define	FE_VXIDI	0x00400000	/* inf / inf */
-#define	FE_VXISI	0x00800000	/* inf - inf */
-#define	FE_VXSNAN	0x01000000	/* operation on a signalling NaN */
-#define	FE_ALL_INVALID	(FE_VXCVI | FE_VXSQRT | FE_VXSOFT | FE_VXVC | \
-			 FE_VXIMZ | FE_VXZDZ | FE_VXIDI | FE_VXISI | \
-			 FE_VXSNAN | FE_INVALID)
-#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_INEXACT | \
-			 FE_ALL_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
-
-/* Rounding modes */
-#define	FE_TONEAREST	0x0000
-#define	FE_TOWARDZERO	0x0001
-#define	FE_UPWARD	0x0002
-#define	FE_DOWNWARD	0x0003
-#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
-			 FE_UPWARD | FE_TOWARDZERO)
-
-__BEGIN_DECLS
-
-/* Default floating-point environment */
-extern const fenv_t	__fe_dfl_env;
-#define	FE_DFL_ENV	(&__fe_dfl_env)
-
-/* We need to be able to map status flag positions to mask flag positions */
-#define	_FPUSW_SHIFT	22
-#define	_ENABLE_MASK	((FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
-			 FE_OVERFLOW | FE_UNDERFLOW) >> _FPUSW_SHIFT)
-
-#define	__mffs(__env)	__asm __volatile("mffs %0" : "=f" (*(__env)))
-#define	__mtfsf(__env)	__asm __volatile("mtfsf 255,%0" : : "f" (__env))
-
-union __fpscr {
-	double __d;
-	struct {
-		__uint32_t __junk;
-		fenv_t __reg;
-	} __bits;
-};
-
-static __inline int
-feclearexcept(int __excepts)
-{
-	union __fpscr __r;
-
-	if (__excepts & FE_INVALID)
-		__excepts |= FE_ALL_INVALID;
-	__mffs(&__r.__d);
-	__r.__bits.__reg &= ~__excepts;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	*__flagp = __r.__bits.__reg & __excepts;
-	return (0);
-}
-
-static __inline int
-fesetexceptflag(const fexcept_t *__flagp, int __excepts)
-{
-	union __fpscr __r;
-
-	if (__excepts & FE_INVALID)
-		__excepts |= FE_ALL_EXCEPT;
-	__mffs(&__r.__d);
-	__r.__bits.__reg &= ~__excepts;
-	__r.__bits.__reg |= *__flagp & __excepts;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-feraiseexcept(int __excepts)
-{
-	union __fpscr __r;
-
-	if (__excepts & FE_INVALID)
-		__excepts |= FE_VXSOFT;
-	__mffs(&__r.__d);
-	__r.__bits.__reg |= __excepts;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-fetestexcept(int __excepts)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	return (__r.__bits.__reg & __excepts);
-}
-
-static __inline int
-fegetround(void)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	return (__r.__bits.__reg & _ROUND_MASK);
-}
-
-static __inline int
-fesetround(int __round)
-{
-	union __fpscr __r;
-
-	if (__round & ~_ROUND_MASK)
-		return (-1);
-	__mffs(&__r.__d);
-	__r.__bits.__reg &= ~_ROUND_MASK;
-	__r.__bits.__reg |= __round;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-fegetenv(fenv_t *__envp)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	*__envp = __r.__bits.__reg;
-	return (0);
-}
-
-static __inline int
-feholdexcept(fenv_t *__envp)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	*__envp = __r.__d;
-	__r.__bits.__reg &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-fesetenv(const fenv_t *__envp)
-{
-	union __fpscr __r;
-
-	__r.__bits.__reg = *__envp;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-feupdateenv(const fenv_t *__envp)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	__r.__bits.__reg &= FE_ALL_EXCEPT;
-	__r.__bits.__reg |= *__envp;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-#if __BSD_VISIBLE
-
-static __inline int
-feenableexcept(int __mask)
-{
-	union __fpscr __r;
-	fenv_t __oldmask;
-
-	__mffs(&__r.__d);
-	__oldmask = __r.__bits.__reg;
-	__r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT;
-	__mtfsf(__r.__d);
-	return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
-}
-
-static __inline int
-fedisableexcept(int __mask)
-{
-	union __fpscr __r;
-	fenv_t __oldmask;
-
-	__mffs(&__r.__d);
-	__oldmask = __r.__bits.__reg;
-	__r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT);
-	__mtfsf(__r.__d);
-	return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
-}
-
-static __inline int
-fegetexcept(void)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	return ((__r.__bits.__reg & _ENABLE_MASK) << _FPUSW_SHIFT);
-}
-
-#endif /* __BSD_VISIBLE */
-
-__END_DECLS
-
-#endif	/* !_FENV_H_ */
diff --git a/libm/include/sparc64/fenv.h b/libm/include/sparc64/fenv.h
deleted file mode 100644
index 684c4a2..0000000
--- a/libm/include/sparc64/fenv.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/sparc64/fenv.h,v 1.3 2005/03/16 19:03:46 das Exp $
- */
-
-#ifndef	_FENV_H_
-#define	_FENV_H_
-
-#include <sys/_types.h>
-
-typedef	__uint64_t	fenv_t;
-typedef	__uint64_t	fexcept_t;
-
-/* Exception flags */
-#define	FE_INVALID	0x00000200
-#define	FE_DIVBYZERO	0x00000040
-#define	FE_OVERFLOW	0x00000100
-#define	FE_UNDERFLOW	0x00000080
-#define	FE_INEXACT	0x00000020
-#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_INEXACT | \
-			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
-
-/*
- * Rounding modes
- *
- * We can't just use the hardware bit values here, because that would
- * make FE_UPWARD and FE_DOWNWARD negative, which is not allowed.
- */
-#define	FE_TONEAREST	0x0
-#define	FE_TOWARDZERO	0x1
-#define	FE_UPWARD	0x2
-#define	FE_DOWNWARD	0x3
-#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
-			 FE_UPWARD | FE_TOWARDZERO)
-#define	_ROUND_SHIFT	30
-
-__BEGIN_DECLS
-
-/* Default floating-point environment */
-extern const fenv_t	__fe_dfl_env;
-#define	FE_DFL_ENV	(&__fe_dfl_env)
-
-/* We need to be able to map status flag positions to mask flag positions */
-#define _FPUSW_SHIFT	18
-#define	_ENABLE_MASK	(FE_ALL_EXCEPT << _FPUSW_SHIFT)
-
-#define	__ldxfsr(__r)	__asm __volatile("ldx %0, %%fsr" : : "m" (__r))
-#define	__stxfsr(__r)	__asm __volatile("stx %%fsr, %0" : "=m" (*(__r)))
-
-static __inline int
-feclearexcept(int __excepts)
-{
-	fexcept_t __r;
-
-	__stxfsr(&__r);
-	__r &= ~__excepts;
-	__ldxfsr(__r);
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	fexcept_t __r;
-
-	__stxfsr(&__r);
-	*__flagp = __r & __excepts;
-	return (0);
-}
-
-static __inline int
-fesetexceptflag(const fexcept_t *__flagp, int __excepts)
-{
-	fexcept_t __r;
-
-	__stxfsr(&__r);
-	__r &= ~__excepts;
-	__r |= *__flagp & __excepts;
-	__ldxfsr(__r);
-	return (0);
-}
-
-/*
- * In contrast with the ia64 platform, it seems to be worthwhile to
- * inline this function on sparc64 even when the arguments are not
- * compile-time constants.  Perhaps this depends on the register window.
- */
-static __inline int
-feraiseexcept(int __excepts)
-{
-	volatile double d;
-
-	/*
-	 * With a compiler that supports the FENV_ACCESS pragma
-	 * properly, simple expressions like '0.0 / 0.0' should
-	 * be sufficient to generate traps.  Unfortunately, we
-	 * need to bring a volatile variable into the equation
-	 * to prevent incorrect optimizations.
-	 */
-	if (__excepts & FE_INVALID) {
-		d = 0.0;
-		d = 0.0 / d;
-	}
-	if (__excepts & FE_DIVBYZERO) {
-		d = 0.0;
-		d = 1.0 / d;
-	}
-	if (__excepts & FE_OVERFLOW) {
-		d = 0x1.ffp1023;
-		d *= 2.0;
-	}
-	if (__excepts & FE_UNDERFLOW) {
-		d = 0x1p-1022;
-		d /= 0x1p1023;
-	}
-	if (__excepts & FE_INEXACT) {
-		d = 0x1p-1022;
-		d += 1.0;
-	}
-	return (0);
-}
-
-static __inline int
-fetestexcept(int __excepts)
-{
-	fexcept_t __r;
-
-	__stxfsr(&__r);
-	return (__r & __excepts);
-}
-
-static __inline int
-fegetround(void)
-{
-	fenv_t __r;
-
-	__stxfsr(&__r);
-	return ((__r >> _ROUND_SHIFT) & _ROUND_MASK);
-}
-
-static __inline int
-fesetround(int __round)
-{
-	fenv_t __r;
-
-	if (__round & ~_ROUND_MASK)
-		return (-1);
-	__stxfsr(&__r);
-	__r &= ~(_ROUND_MASK << _ROUND_SHIFT);
-	__r |= __round << _ROUND_SHIFT;
-	__ldxfsr(__r);
-	return (0);
-}
-
-static __inline int
-fegetenv(fenv_t *__envp)
-{
-
-	__stxfsr(__envp);
-	return (0);
-}
-
-static __inline int
-feholdexcept(fenv_t *__envp)
-{
-	fenv_t __r;
-
-	__stxfsr(&__r);
-	*__envp = __r;
-	__r &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
-	__ldxfsr(__r);
-	return (0);
-}
-
-static __inline int
-fesetenv(const fenv_t *__envp)
-{
-
-	__ldxfsr(*__envp);
-	return (0);
-}
-
-static __inline int
-feupdateenv(const fenv_t *__envp)
-{
-	fexcept_t __r;
-
-	__stxfsr(&__r);
-	__ldxfsr(*__envp);
-	feraiseexcept(__r & FE_ALL_EXCEPT);
-	return (0);
-}
-
-#if __BSD_VISIBLE
-
-static __inline int
-feenableexcept(int __mask)
-{
-	fenv_t __old_r, __new_r;
-
-	__stxfsr(&__old_r);
-	__new_r = __old_r | ((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
-	__ldxfsr(__new_r);
-	return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
-}
-
-static __inline int
-fedisableexcept(int __mask)
-{
-	fenv_t __old_r, __new_r;
-
-	__stxfsr(&__old_r);
-	__new_r = __old_r & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
-	__ldxfsr(__new_r);
-	return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
-}
-
-static __inline int
-fegetexcept(void)
-{
-	fenv_t __r;
-
-	__stxfsr(&__r);
-	return ((__r & _ENABLE_MASK) >> _FPUSW_SHIFT);
-}
-
-#endif /* __BSD_VISIBLE */
-
-__END_DECLS
-
-#endif	/* !_FENV_H_ */
diff --git a/libm/mips/Makefile.inc b/libm/mips/Makefile.inc
deleted file mode 100644
index 9bbfaa1..0000000
--- a/libm/mips/Makefile.inc
+++ /dev/null
@@ -1,3 +0,0 @@
-# $FreeBSD: src/lib/msun/mips/Makefile.inc,v 1.1 2008/04/26 12:20:29 imp Exp $
-
-LDBL_PREC = 53
diff --git a/libm/powerpc/Makefile.inc b/libm/powerpc/Makefile.inc
deleted file mode 100644
index 7eb3700..0000000
--- a/libm/powerpc/Makefile.inc
+++ /dev/null
@@ -1,3 +0,0 @@
-# $FreeBSD: src/lib/msun/powerpc/Makefile.inc,v 1.1 2005/03/07 04:53:36 das Exp $
-
-LDBL_PREC = 53
diff --git a/libm/powerpc/_fpmath.h b/libm/powerpc/_fpmath.h
deleted file mode 100644
index 5285cb9..0000000
--- a/libm/powerpc/_fpmath.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-
- * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libc/powerpc/_fpmath.h,v 1.7 2005/03/07 04:55:22 das Exp $
- */
-
-union IEEEl2bits {
-	long double	e;
-	struct {
-		unsigned int		sign	:1;
-		unsigned int		exp	:11;
-		unsigned int		manh	:20;
-		unsigned int		manl	:32;
-	} bits;
-};
-
-#define	mask_nbit_l(u)	((void)0)
-#define	LDBL_IMPLICIT_NBIT
-#define	LDBL_NBIT	0
-
-#define	LDBL_MANH_SIZE	20
-#define	LDBL_MANL_SIZE	32
-
-#define	LDBL_TO_ARRAY32(u, a) do {			\
-	(a)[0] = (uint32_t)(u).bits.manl;		\
-	(a)[1] = (uint32_t)(u).bits.manh;		\
-} while(0)
diff --git a/libm/powerpc/fenv.c b/libm/powerpc/fenv.c
deleted file mode 100644
index a8fa87a..0000000
--- a/libm/powerpc/fenv.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*-
- * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/powerpc/fenv.c,v 1.1 2004/06/06 10:05:10 das Exp $
- */
-
-#include <fenv.h>
-
-const fenv_t __fe_dfl_env = 0x00000000;
diff --git a/libm/powerpc/fenv.h b/libm/powerpc/fenv.h
deleted file mode 100644
index 3fd2389..0000000
--- a/libm/powerpc/fenv.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/powerpc/fenv.h,v 1.3 2005/03/16 19:03:45 das Exp $
- */
-
-#ifndef	_FENV_H_
-#define	_FENV_H_
-
-#include <sys/_types.h>
-
-typedef	__uint32_t	fenv_t;
-typedef	__uint32_t	fexcept_t;
-
-/* Exception flags */
-#define	FE_INEXACT	0x02000000
-#define	FE_DIVBYZERO	0x04000000
-#define	FE_UNDERFLOW	0x08000000
-#define	FE_OVERFLOW	0x10000000
-#define	FE_INVALID	0x20000000	/* all types of invalid FP ops */
-
-/*
- * The PowerPC architecture has extra invalid flags that indicate the
- * specific type of invalid operation occurred.  These flags may be
- * tested, set, and cleared---but not masked---separately.  All of
- * these bits are cleared when FE_INVALID is cleared, but only
- * FE_VXSOFT is set when FE_INVALID is explicitly set in software.
- */
-#define	FE_VXCVI	0x00000100	/* invalid integer convert */
-#define	FE_VXSQRT	0x00000200	/* square root of a negative */
-#define	FE_VXSOFT	0x00000400	/* software-requested exception */
-#define	FE_VXVC		0x00080000	/* ordered comparison involving NaN */
-#define	FE_VXIMZ	0x00100000	/* inf * 0 */
-#define	FE_VXZDZ	0x00200000	/* 0 / 0 */
-#define	FE_VXIDI	0x00400000	/* inf / inf */
-#define	FE_VXISI	0x00800000	/* inf - inf */
-#define	FE_VXSNAN	0x01000000	/* operation on a signalling NaN */
-#define	FE_ALL_INVALID	(FE_VXCVI | FE_VXSQRT | FE_VXSOFT | FE_VXVC | \
-			 FE_VXIMZ | FE_VXZDZ | FE_VXIDI | FE_VXISI | \
-			 FE_VXSNAN | FE_INVALID)
-#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_INEXACT | \
-			 FE_ALL_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
-
-/* Rounding modes */
-#define	FE_TONEAREST	0x0000
-#define	FE_TOWARDZERO	0x0001
-#define	FE_UPWARD	0x0002
-#define	FE_DOWNWARD	0x0003
-#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
-			 FE_UPWARD | FE_TOWARDZERO)
-
-__BEGIN_DECLS
-
-/* Default floating-point environment */
-extern const fenv_t	__fe_dfl_env;
-#define	FE_DFL_ENV	(&__fe_dfl_env)
-
-/* We need to be able to map status flag positions to mask flag positions */
-#define	_FPUSW_SHIFT	22
-#define	_ENABLE_MASK	((FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
-			 FE_OVERFLOW | FE_UNDERFLOW) >> _FPUSW_SHIFT)
-
-#define	__mffs(__env)	__asm __volatile("mffs %0" : "=f" (*(__env)))
-#define	__mtfsf(__env)	__asm __volatile("mtfsf 255,%0" : : "f" (__env))
-
-union __fpscr {
-	double __d;
-	struct {
-		__uint32_t __junk;
-		fenv_t __reg;
-	} __bits;
-};
-
-static __inline int
-feclearexcept(int __excepts)
-{
-	union __fpscr __r;
-
-	if (__excepts & FE_INVALID)
-		__excepts |= FE_ALL_INVALID;
-	__mffs(&__r.__d);
-	__r.__bits.__reg &= ~__excepts;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	*__flagp = __r.__bits.__reg & __excepts;
-	return (0);
-}
-
-static __inline int
-fesetexceptflag(const fexcept_t *__flagp, int __excepts)
-{
-	union __fpscr __r;
-
-	if (__excepts & FE_INVALID)
-		__excepts |= FE_ALL_EXCEPT;
-	__mffs(&__r.__d);
-	__r.__bits.__reg &= ~__excepts;
-	__r.__bits.__reg |= *__flagp & __excepts;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-feraiseexcept(int __excepts)
-{
-	union __fpscr __r;
-
-	if (__excepts & FE_INVALID)
-		__excepts |= FE_VXSOFT;
-	__mffs(&__r.__d);
-	__r.__bits.__reg |= __excepts;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-fetestexcept(int __excepts)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	return (__r.__bits.__reg & __excepts);
-}
-
-static __inline int
-fegetround(void)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	return (__r.__bits.__reg & _ROUND_MASK);
-}
-
-static __inline int
-fesetround(int __round)
-{
-	union __fpscr __r;
-
-	if (__round & ~_ROUND_MASK)
-		return (-1);
-	__mffs(&__r.__d);
-	__r.__bits.__reg &= ~_ROUND_MASK;
-	__r.__bits.__reg |= __round;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-fegetenv(fenv_t *__envp)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	*__envp = __r.__bits.__reg;
-	return (0);
-}
-
-static __inline int
-feholdexcept(fenv_t *__envp)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	*__envp = __r.__d;
-	__r.__bits.__reg &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-fesetenv(const fenv_t *__envp)
-{
-	union __fpscr __r;
-
-	__r.__bits.__reg = *__envp;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-static __inline int
-feupdateenv(const fenv_t *__envp)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	__r.__bits.__reg &= FE_ALL_EXCEPT;
-	__r.__bits.__reg |= *__envp;
-	__mtfsf(__r.__d);
-	return (0);
-}
-
-#if __BSD_VISIBLE
-
-static __inline int
-feenableexcept(int __mask)
-{
-	union __fpscr __r;
-	fenv_t __oldmask;
-
-	__mffs(&__r.__d);
-	__oldmask = __r.__bits.__reg;
-	__r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT;
-	__mtfsf(__r.__d);
-	return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
-}
-
-static __inline int
-fedisableexcept(int __mask)
-{
-	union __fpscr __r;
-	fenv_t __oldmask;
-
-	__mffs(&__r.__d);
-	__oldmask = __r.__bits.__reg;
-	__r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT);
-	__mtfsf(__r.__d);
-	return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
-}
-
-static __inline int
-fegetexcept(void)
-{
-	union __fpscr __r;
-
-	__mffs(&__r.__d);
-	return ((__r.__bits.__reg & _ENABLE_MASK) << _FPUSW_SHIFT);
-}
-
-#endif /* __BSD_VISIBLE */
-
-__END_DECLS
-
-#endif	/* !_FENV_H_ */
diff --git a/libm/sparc64/Makefile.inc b/libm/sparc64/Makefile.inc
deleted file mode 100644
index e883fa9..0000000
--- a/libm/sparc64/Makefile.inc
+++ /dev/null
@@ -1,4 +0,0 @@
-# $FreeBSD: src/lib/msun/sparc64/Makefile.inc,v 1.2 2005/03/07 04:53:36 das Exp $
-
-ARCH_SRCS= e_sqrt.S e_sqrtf.S
-LDBL_PREC= 113
diff --git a/libm/sparc64/_fpmath.h b/libm/sparc64/_fpmath.h
deleted file mode 100644
index 4afaab9..0000000
--- a/libm/sparc64/_fpmath.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
- * Copyright (c) 2002, 2003 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libc/sparc64/_fpmath.h,v 1.5 2005/03/07 04:55:22 das Exp $
- */
-
-union IEEEl2bits {
-	long double	e;
-	struct {
-		unsigned int	sign	:1;
-		unsigned int	exp	:15;
-		unsigned long	manh	:48;
-		unsigned long	manl	:64;
-	} bits;
-};
-
-#define	mask_nbit_l(u)	((void)0)
-#define	LDBL_IMPLICIT_NBIT
-#define	LDBL_NBIT	0
-
-#define	LDBL_MANH_SIZE	48
-#define	LDBL_MANL_SIZE	64
-
-#define	LDBL_TO_ARRAY32(u, a) do {			\
-	(a)[0] = (uint32_t)(u).bits.manl;		\
-	(a)[1] = (uint32_t)((u).bits.manl >> 32);      	\
-	(a)[2] = (uint32_t)(u).bits.manh;		\
-	(a)[3] = (uint32_t)((u).bits.manh >> 32);	\
-} while(0)
diff --git a/libm/sparc64/e_sqrt.S b/libm/sparc64/e_sqrt.S
deleted file mode 100644
index 95f79a6..0000000
--- a/libm/sparc64/e_sqrt.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/sparc64/e_sqrt.S,v 1.1 2005/02/21 18:27:57 das Exp $")
-
-ENTRY(sqrt)
-	retl
-	fsqrtd %f0, %f0
-END(sqrt)
diff --git a/libm/sparc64/e_sqrtf.S b/libm/sparc64/e_sqrtf.S
deleted file mode 100644
index e1f7cf6..0000000
--- a/libm/sparc64/e_sqrtf.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/*-
- * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-__FBSDID("$FreeBSD: src/lib/msun/sparc64/e_sqrtf.S,v 1.1 2005/02/21 18:27:57 das Exp $")
-
-ENTRY(sqrtf)
-	retl
-	fsqrts %f1, %f0
-END(sqrtf)
diff --git a/libm/sparc64/fenv.c b/libm/sparc64/fenv.c
deleted file mode 100644
index 79a0f64..0000000
--- a/libm/sparc64/fenv.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*-
- * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/sparc64/fenv.c,v 1.1 2004/06/06 10:05:57 das Exp $
- */
-
-#include <fenv.h>
-
-/*
- * The FSR_version field may be different on different
- * implementations, but it is immutable and opaque to the
- * application.  Thus, 0 is valid as the default environment.
- */
-const fenv_t __fe_dfl_env = 0;
diff --git a/libm/sparc64/fenv.h b/libm/sparc64/fenv.h
deleted file mode 100644
index 684c4a2..0000000
--- a/libm/sparc64/fenv.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*-
- * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/msun/sparc64/fenv.h,v 1.3 2005/03/16 19:03:46 das Exp $
- */
-
-#ifndef	_FENV_H_
-#define	_FENV_H_
-
-#include <sys/_types.h>
-
-typedef	__uint64_t	fenv_t;
-typedef	__uint64_t	fexcept_t;
-
-/* Exception flags */
-#define	FE_INVALID	0x00000200
-#define	FE_DIVBYZERO	0x00000040
-#define	FE_OVERFLOW	0x00000100
-#define	FE_UNDERFLOW	0x00000080
-#define	FE_INEXACT	0x00000020
-#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_INEXACT | \
-			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
-
-/*
- * Rounding modes
- *
- * We can't just use the hardware bit values here, because that would
- * make FE_UPWARD and FE_DOWNWARD negative, which is not allowed.
- */
-#define	FE_TONEAREST	0x0
-#define	FE_TOWARDZERO	0x1
-#define	FE_UPWARD	0x2
-#define	FE_DOWNWARD	0x3
-#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
-			 FE_UPWARD | FE_TOWARDZERO)
-#define	_ROUND_SHIFT	30
-
-__BEGIN_DECLS
-
-/* Default floating-point environment */
-extern const fenv_t	__fe_dfl_env;
-#define	FE_DFL_ENV	(&__fe_dfl_env)
-
-/* We need to be able to map status flag positions to mask flag positions */
-#define _FPUSW_SHIFT	18
-#define	_ENABLE_MASK	(FE_ALL_EXCEPT << _FPUSW_SHIFT)
-
-#define	__ldxfsr(__r)	__asm __volatile("ldx %0, %%fsr" : : "m" (__r))
-#define	__stxfsr(__r)	__asm __volatile("stx %%fsr, %0" : "=m" (*(__r)))
-
-static __inline int
-feclearexcept(int __excepts)
-{
-	fexcept_t __r;
-
-	__stxfsr(&__r);
-	__r &= ~__excepts;
-	__ldxfsr(__r);
-	return (0);
-}
-
-static __inline int
-fegetexceptflag(fexcept_t *__flagp, int __excepts)
-{
-	fexcept_t __r;
-
-	__stxfsr(&__r);
-	*__flagp = __r & __excepts;
-	return (0);
-}
-
-static __inline int
-fesetexceptflag(const fexcept_t *__flagp, int __excepts)
-{
-	fexcept_t __r;
-
-	__stxfsr(&__r);
-	__r &= ~__excepts;
-	__r |= *__flagp & __excepts;
-	__ldxfsr(__r);
-	return (0);
-}
-
-/*
- * In contrast with the ia64 platform, it seems to be worthwhile to
- * inline this function on sparc64 even when the arguments are not
- * compile-time constants.  Perhaps this depends on the register window.
- */
-static __inline int
-feraiseexcept(int __excepts)
-{
-	volatile double d;
-
-	/*
-	 * With a compiler that supports the FENV_ACCESS pragma
-	 * properly, simple expressions like '0.0 / 0.0' should
-	 * be sufficient to generate traps.  Unfortunately, we
-	 * need to bring a volatile variable into the equation
-	 * to prevent incorrect optimizations.
-	 */
-	if (__excepts & FE_INVALID) {
-		d = 0.0;
-		d = 0.0 / d;
-	}
-	if (__excepts & FE_DIVBYZERO) {
-		d = 0.0;
-		d = 1.0 / d;
-	}
-	if (__excepts & FE_OVERFLOW) {
-		d = 0x1.ffp1023;
-		d *= 2.0;
-	}
-	if (__excepts & FE_UNDERFLOW) {
-		d = 0x1p-1022;
-		d /= 0x1p1023;
-	}
-	if (__excepts & FE_INEXACT) {
-		d = 0x1p-1022;
-		d += 1.0;
-	}
-	return (0);
-}
-
-static __inline int
-fetestexcept(int __excepts)
-{
-	fexcept_t __r;
-
-	__stxfsr(&__r);
-	return (__r & __excepts);
-}
-
-static __inline int
-fegetround(void)
-{
-	fenv_t __r;
-
-	__stxfsr(&__r);
-	return ((__r >> _ROUND_SHIFT) & _ROUND_MASK);
-}
-
-static __inline int
-fesetround(int __round)
-{
-	fenv_t __r;
-
-	if (__round & ~_ROUND_MASK)
-		return (-1);
-	__stxfsr(&__r);
-	__r &= ~(_ROUND_MASK << _ROUND_SHIFT);
-	__r |= __round << _ROUND_SHIFT;
-	__ldxfsr(__r);
-	return (0);
-}
-
-static __inline int
-fegetenv(fenv_t *__envp)
-{
-
-	__stxfsr(__envp);
-	return (0);
-}
-
-static __inline int
-feholdexcept(fenv_t *__envp)
-{
-	fenv_t __r;
-
-	__stxfsr(&__r);
-	*__envp = __r;
-	__r &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
-	__ldxfsr(__r);
-	return (0);
-}
-
-static __inline int
-fesetenv(const fenv_t *__envp)
-{
-
-	__ldxfsr(*__envp);
-	return (0);
-}
-
-static __inline int
-feupdateenv(const fenv_t *__envp)
-{
-	fexcept_t __r;
-
-	__stxfsr(&__r);
-	__ldxfsr(*__envp);
-	feraiseexcept(__r & FE_ALL_EXCEPT);
-	return (0);
-}
-
-#if __BSD_VISIBLE
-
-static __inline int
-feenableexcept(int __mask)
-{
-	fenv_t __old_r, __new_r;
-
-	__stxfsr(&__old_r);
-	__new_r = __old_r | ((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
-	__ldxfsr(__new_r);
-	return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
-}
-
-static __inline int
-fedisableexcept(int __mask)
-{
-	fenv_t __old_r, __new_r;
-
-	__stxfsr(&__old_r);
-	__new_r = __old_r & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
-	__ldxfsr(__new_r);
-	return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
-}
-
-static __inline int
-fegetexcept(void)
-{
-	fenv_t __r;
-
-	__stxfsr(&__r);
-	return ((__r & _ENABLE_MASK) >> _FPUSW_SHIFT);
-}
-
-#endif /* __BSD_VISIBLE */
-
-__END_DECLS
-
-#endif	/* !_FENV_H_ */
diff --git a/linker/debugger.cpp b/linker/debugger.cpp
index bba89b8..28c939a 100644
--- a/linker/debugger.cpp
+++ b/linker/debugger.cpp
@@ -32,7 +32,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <stdbool.h>
 #include <signal.h>
 #include <sys/prctl.h>
 #include <errno.h>
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index c87d29a..24006e2 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -57,13 +57,11 @@
 
 void* dlopen(const char* filename, int flag) {
   ScopedPthreadMutexLocker locker(&gDlMutex);
-  soinfo* result = find_library(filename);
+  soinfo* result = do_dlopen(filename);
   if (result == NULL) {
     __bionic_format_dlerror("dlopen failed", linker_get_error());
     return NULL;
   }
-  soinfo_call_constructors(result);
-  result->refcount++;
   return result;
 }
 
@@ -139,7 +137,7 @@
 
 int dlclose(void* handle) {
   ScopedPthreadMutexLocker locker(&gDlMutex);
-  return soinfo_unload((soinfo*) handle);
+  return do_dlclose(reinterpret_cast<soinfo*>(handle));
 }
 
 #if defined(ANDROID_ARM_LINKER)
@@ -236,7 +234,8 @@
 
     refcount: 0,
     { l_addr: 0, l_name: 0, l_ld: 0, l_next: 0, l_prev: 0, },
-    constructors_called: 0, load_bias: 0,
+    constructors_called: false,
+    load_bias: 0,
     has_text_relocations: false,
     has_DT_SYMBOLIC: true,
 };
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 8bb989a..e064ccf 100755
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -31,7 +31,6 @@
 #include <fcntl.h>
 #include <linux/auxvec.h>
 #include <pthread.h>
-#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -51,8 +50,6 @@
 #include "linker_format.h"
 #include "linker_phdr.h"
 
-#define SO_MAX 128
-
 /* Assume average path length of 64 and max 8 paths */
 #define LDPATH_BUFSIZE 512
 #define LDPATH_MAX 8
@@ -74,27 +71,36 @@
  * - cleaner error reporting
  * - after linking, set as much stuff as possible to READONLY
  *   and NOEXEC
- * - linker hardcodes PAGE_SIZE and PAGE_MASK because the kernel
- *   headers provide versions that are negative...
- * - allocate space for soinfo structs dynamically instead of
- *   having a hard limit (SO_MAX)
  */
 
+static bool soinfo_link_image(soinfo* si);
 
-static int soinfo_link_image(soinfo *si);
+// We can't use malloc(3) in the dynamic linker. We use a linked list of anonymous
+// maps, each a single page in size. The pages are broken up into as many struct soinfo
+// objects as will fit, and they're all threaded together on a free list.
+#define SOINFO_PER_POOL ((PAGE_SIZE - sizeof(soinfo_pool_t*)) / sizeof(soinfo))
+struct soinfo_pool_t {
+  soinfo_pool_t* next;
+  soinfo info[SOINFO_PER_POOL];
+};
+static struct soinfo_pool_t* gSoInfoPools = NULL;
+static soinfo* gSoInfoFreeList = NULL;
 
-static int socount = 0;
-static soinfo sopool[SO_MAX];
-static soinfo *freelist = NULL;
 static soinfo *solist = &libdl_info;
 static soinfo *sonext = &libdl_info;
 static soinfo *somain; /* main process, always the one after libdl_info */
 
-static char ldpaths_buf[LDPATH_BUFSIZE];
-static const char *ldpaths[LDPATH_MAX + 1];
+static const char* const gSoPaths[] = {
+  "/vendor/lib",
+  "/system/lib",
+  NULL
+};
 
-static char ldpreloads_buf[LDPRELOAD_BUFSIZE];
-static const char *ldpreload_names[LDPRELOAD_MAX + 1];
+static char gLdPathsBuffer[LDPATH_BUFSIZE];
+static const char* gLdPaths[LDPATH_MAX + 1];
+
+static char gLdPreloadsBuffer[LDPRELOAD_BUFSIZE];
+static const char* gLdPreloadNames[LDPRELOAD_MAX + 1];
 
 static soinfo *preloads[LDPRELOAD_MAX + 1];
 
@@ -257,38 +263,65 @@
     rtld_db_dlactivity();
 }
 
-static soinfo *soinfo_alloc(const char *name)
-{
-    if (strlen(name) >= SOINFO_NAME_LEN) {
-        DL_ERR("library name \"%s\" too long", name);
-        return NULL;
+static bool ensure_free_list_non_empty() {
+  if (gSoInfoFreeList != NULL) {
+    return true;
+  }
+
+  // Allocate a new pool.
+  soinfo_pool_t* pool = reinterpret_cast<soinfo_pool_t*>(mmap(NULL, sizeof(*pool),
+                                                              PROT_READ|PROT_WRITE,
+                                                              MAP_PRIVATE|MAP_ANONYMOUS, 0, 0));
+  if (pool == MAP_FAILED) {
+    return false;
+  }
+
+  // Add the pool to our list of pools.
+  pool->next = gSoInfoPools;
+  gSoInfoPools = pool;
+
+  // Chain the entries in the new pool onto the free list.
+  gSoInfoFreeList = &pool->info[0];
+  soinfo* next = NULL;
+  for (int i = SOINFO_PER_POOL - 1; i >= 0; --i) {
+    pool->info[i].next = next;
+    next = &pool->info[i];
+  }
+
+  return true;
+}
+
+static void set_soinfo_pool_protection(int protection) {
+  for (soinfo_pool_t* p = gSoInfoPools; p != NULL; p = p->next) {
+    if (mprotect(p, sizeof(*p), protection) == -1) {
+      abort(); // Can't happen.
     }
+  }
+}
 
-    /* The freelist is populated when we call soinfo_free(), which in turn is
-       done only by dlclose(), which is not likely to be used.
-    */
-    if (!freelist) {
-        if (socount == SO_MAX) {
-            DL_ERR("too many libraries when loading \"%s\"", name);
-            return NULL;
-        }
-        freelist = sopool + socount++;
-        freelist->next = NULL;
-    }
+static soinfo* soinfo_alloc(const char* name) {
+  if (strlen(name) >= SOINFO_NAME_LEN) {
+    DL_ERR("library name \"%s\" too long", name);
+    return NULL;
+  }
 
-    soinfo* si = freelist;
-    freelist = freelist->next;
+  if (!ensure_free_list_non_empty()) {
+    DL_ERR("out of memory when loading \"%s\"", name);
+    return NULL;
+  }
 
-    /* Make sure we get a clean block of soinfo */
-    memset(si, 0, sizeof(soinfo));
-    strlcpy((char*) si->name, name, sizeof(si->name));
-    sonext->next = si;
-    si->next = NULL;
-    si->refcount = 0;
-    sonext = si;
+  // Take the head element off the free list.
+  soinfo* si = gSoInfoFreeList;
+  gSoInfoFreeList = gSoInfoFreeList->next;
 
-    TRACE("%5d name %s: allocated soinfo @ %p\n", pid, name, si);
-    return si;
+  // Initialize the new element.
+  memset(si, 0, sizeof(soinfo));
+  strlcpy(si->name, name, sizeof(si->name));
+  sonext->next = si;
+  sonext = si;
+
+  TRACE("%5d name %s: allocated soinfo @ %p\n", pid, name, si);
+  return si;
 }
 
 static void soinfo_free(soinfo* si)
@@ -317,8 +350,8 @@
     */
     prev->next = si->next;
     if (si == sonext) sonext = prev;
-    si->next = freelist;
-    freelist = si;
+    si->next = gSoInfoFreeList;
+    gSoInfoFreeList = si;
 }
 
 #ifdef ANDROID_ARM_LINKER
@@ -610,56 +643,40 @@
 }
 #endif
 
-static const char * const sopaths[] = {
-    "/vendor/lib",
-    "/system/lib",
-    0
-};
-
-static int _open_lib(const char* name) {
-    // TODO: why not just call open?
-    struct stat sb;
-    if (stat(name, &sb) == -1 || !S_ISREG(sb.st_mode)) {
-        return -1;
+static int open_library_on_path(const char* name, const char* const paths[]) {
+  char buf[512];
+  for (size_t i = 0; paths[i] != NULL; ++i) {
+    int n = format_buffer(buf, sizeof(buf), "%s/%s", paths[i], name);
+    if (n < 0 || n >= static_cast<int>(sizeof(buf))) {
+      WARN("Ignoring very long library path: %s/%s\n", paths[i], name);
+      continue;
     }
-    return TEMP_FAILURE_RETRY(open(name, O_RDONLY));
+    int fd = TEMP_FAILURE_RETRY(open(buf, O_RDONLY | O_CLOEXEC));
+    if (fd != -1) {
+      return fd;
+    }
+  }
+  return -1;
 }
 
-static int open_library(const char *name)
-{
-    int fd;
-    char buf[512];
-    const char * const*path;
-    int n;
+static int open_library(const char* name) {
+  TRACE("[ %5d opening %s ]\n", pid, name);
 
-    TRACE("[ %5d opening %s ]\n", pid, name);
-
-    if(name == 0) return -1;
-    if(strlen(name) > 256) return -1;
-
-    if ((name[0] == '/') && ((fd = _open_lib(name)) >= 0))
-        return fd;
-
-    for (path = ldpaths; *path; path++) {
-        n = format_buffer(buf, sizeof(buf), "%s/%s", *path, name);
-        if (n < 0 || n >= (int)sizeof(buf)) {
-            WARN("Ignoring very long library path: %s/%s\n", *path, name);
-            continue;
-        }
-        if ((fd = _open_lib(buf)) >= 0)
-            return fd;
+  // If the name contains a slash, we should attempt to open it directly and not search the paths.
+  if (strchr(name, '/') != NULL) {
+    int fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CLOEXEC));
+    if (fd != -1) {
+      return fd;
     }
-    for (path = sopaths; *path; path++) {
-        n = format_buffer(buf, sizeof(buf), "%s/%s", *path, name);
-        if (n < 0 || n >= (int)sizeof(buf)) {
-            WARN("Ignoring very long library path: %s/%s\n", *path, name);
-            continue;
-        }
-        if ((fd = _open_lib(buf)) >= 0)
-            return fd;
-    }
+    // ...but nvidia binary blobs (at least) rely on this behavior, so fall through for now.
+  }
 
-    return -1;
+  // Otherwise we try LD_LIBRARY_PATH first, and fall back to the built-in well known paths.
+  int fd = open_library_on_path(name, gLdPaths);
+  if (fd == -1) {
+    fd = open_library_on_path(name, gSoPaths);
+  }
+  return fd;
 }
 
 // Returns 'true' if the library is prelinked or on failure so we error out
@@ -757,8 +774,7 @@
     Elf32_Addr phdr_size;
 };
 
-static soinfo* load_library(const char* name)
-{
+static soinfo* load_library(const char* name) {
     // Open the file.
     scoped_fd fd;
     fd.fd = open_library(name);
@@ -857,20 +873,18 @@
     return si.release();
 }
 
-static soinfo *
-init_library(soinfo *si)
-{
-    /* At this point we know that whatever is loaded @ base is a valid ELF
-     * shared library whose segments are properly mapped in. */
-    TRACE("[ %5d init_library base=0x%08x sz=0x%08x name='%s') ]\n",
-          pid, si->base, si->size, si->name);
+static soinfo* init_library(soinfo* si) {
+  // At this point we know that whatever is loaded @ base is a valid ELF
+  // shared library whose segments are properly mapped in.
+  TRACE("[ %5d init_library base=0x%08x sz=0x%08x name='%s') ]\n",
+        pid, si->base, si->size, si->name);
 
-    if(soinfo_link_image(si)) {
-        munmap((void *)si->base, si->size);
-        return NULL;
-    }
+  if (!soinfo_link_image(si)) {
+    munmap((void *)si->base, si->size);
+    return NULL;
+  }
 
-    return si;
+  return si;
 }
 
 static soinfo *find_loaded_library(const char *name)
@@ -892,63 +906,86 @@
     return NULL;
 }
 
-soinfo *find_library(const char *name)
-{
-    soinfo *si;
+static soinfo* find_library_internal(const char* name) {
+  if (name == NULL) {
+    return somain;
+  }
 
-    if (name == NULL)
-        return somain;
-
-    si = find_loaded_library(name);
-    if (si != NULL) {
-        if(si->flags & FLAG_ERROR) {
-            DL_ERR("\"%s\" failed to load previously", name);
-            return NULL;
-        }
-        if(si->flags & FLAG_LINKED) return si;
-        DL_ERR("OOPS: recursive link to \"%s\"", si->name);
-        return NULL;
+  soinfo* si = find_loaded_library(name);
+  if (si != NULL) {
+    if (si->flags & FLAG_ERROR) {
+      DL_ERR("\"%s\" failed to load previously", name);
+      return NULL;
     }
+    if (si->flags & FLAG_LINKED) {
+      return si;
+    }
+    DL_ERR("OOPS: recursive link to \"%s\"", si->name);
+    return NULL;
+  }
 
-    TRACE("[ %5d '%s' has not been loaded yet.  Locating...]\n", pid, name);
-    si = load_library(name);
-    if(si == NULL)
-        return NULL;
-    return init_library(si);
+  TRACE("[ %5d '%s' has not been loaded yet.  Locating...]\n", pid, name);
+  si = load_library(name);
+  if (si != NULL) {
+    si = init_library(si);
+  }
+
+  return si;
 }
 
-static void call_destructors(soinfo *si);
+static soinfo* find_library(const char* name) {
+  soinfo* si = find_library_internal(name);
+  if (si != NULL) {
+    si->refcount++;
+  }
+  return si;
+}
 
-int soinfo_unload(soinfo* si) {
-    if (si->refcount == 1) {
-        TRACE("%5d unloading '%s'\n", pid, si->name);
-        call_destructors(si);
+static int soinfo_unload(soinfo* si) {
+  if (si->refcount == 1) {
+    TRACE("%5d unloading '%s'\n", pid, si->name);
+    si->CallDestructors();
 
-        for (unsigned* d = si->dynamic; *d; d += 2) {
-            if(d[0] == DT_NEEDED){
-                soinfo *lsi = find_loaded_library(si->strtab + d[1]);
-                if (lsi) {
-                    TRACE("%5d %s needs to unload %s\n", pid,
-                          si->name, lsi->name);
-                    soinfo_unload(lsi);
-                } else {
-                    // TODO: should we return -1 in this case?
-                    DL_ERR("\"%s\": could not unload dependent library",
-                           si->name);
-                }
-            }
+    for (unsigned* d = si->dynamic; *d; d += 2) {
+      if (d[0] == DT_NEEDED) {
+        soinfo* lsi = find_loaded_library(si->strtab + d[1]);
+        if (lsi != NULL) {
+          TRACE("%5d %s needs to unload %s\n", pid, si->name, lsi->name);
+          soinfo_unload(lsi);
+        } else {
+          // TODO: should we return -1 in this case?
+          DL_ERR("\"%s\": could not unload dependent library", si->name);
         }
-
-        munmap((char *)si->base, si->size);
-        notify_gdb_of_unload(si);
-        soinfo_free(si);
-        si->refcount = 0;
-    } else {
-        si->refcount--;
-        PRINT("%5d not unloading '%s', decrementing refcount to %d\n",
-              pid, si->name, si->refcount);
+      }
     }
-    return 0;
+
+    munmap(reinterpret_cast<void*>(si->base), si->size);
+    notify_gdb_of_unload(si);
+    soinfo_free(si);
+    si->refcount = 0;
+  } else {
+    si->refcount--;
+    PRINT("%5d not unloading '%s', decrementing refcount to %d\n",
+          pid, si->name, si->refcount);
+  }
+  return 0;
+}
+
+soinfo* do_dlopen(const char* name) {
+  set_soinfo_pool_protection(PROT_READ | PROT_WRITE);
+  soinfo* si = find_library(name);
+  if (si != NULL) {
+    si->CallConstructors();
+  }
+  set_soinfo_pool_protection(PROT_READ);
+  return si;
+}
+
+int do_dlclose(soinfo* si) {
+  set_soinfo_pool_protection(PROT_READ | PROT_WRITE);
+  int result = soinfo_unload(si);
+  set_soinfo_pool_protection(PROT_READ);
+  return result;
 }
 
 /* TODO: don't use unsigned for addrs below. It works, but is not
@@ -1294,106 +1331,89 @@
  *
  *   DT_FINI_ARRAY must be parsed in reverse order.
  */
+void soinfo::CallArray(const char* array_name UNUSED, unsigned* array, int count, bool reverse) {
+  if (array == NULL) {
+    return;
+  }
 
-static void call_array(unsigned *ctor, int count, int reverse)
-{
-    int n, inc = 1;
+  int step = 1;
+  if (reverse) {
+    array += (count-1);
+    step = -1;
+  }
 
-    if (reverse) {
-        ctor += (count-1);
-        inc   = -1;
+  TRACE("[ %5d Calling %s @ %p [%d] for '%s' ]\n", pid, array_name, array, count, name);
+
+  for (int n = count; n > 0; n--) {
+    TRACE("[ %5d Looking at %s[%d] *%p == 0x%08x ]\n", pid, array_name, n, array, *array);
+    void (*func)() = (void (*)()) *array;
+    array += step;
+    if (((int) func == 0) || ((int) func == -1)) {
+      continue;
     }
+    TRACE("[ %5d Calling func @ %p ]\n", pid, func);
+    func();
+  }
 
-    for(n = count; n > 0; n--) {
-        TRACE("[ %5d Looking at %s *0x%08x == 0x%08x ]\n", pid,
-              reverse ? "dtor" : "ctor",
-              (unsigned)ctor, (unsigned)*ctor);
-        void (*func)() = (void (*)()) *ctor;
-        ctor += inc;
-        if(((int) func == 0) || ((int) func == -1)) continue;
-        TRACE("[ %5d Calling func @ 0x%08x ]\n", pid, (unsigned)func);
-        func();
-    }
+  TRACE("[ %5d Done calling %s for '%s' ]\n", pid, array_name, name);
 }
 
-static void soinfo_call_preinit_constructors(soinfo *si)
-{
-  TRACE("[ %5d Calling preinit_array @ 0x%08x [%d] for '%s' ]\n",
-      pid, (unsigned)si->preinit_array, si->preinit_array_count,
-      si->name);
-  call_array(si->preinit_array, si->preinit_array_count, 0);
-  TRACE("[ %5d Done calling preinit_array for '%s' ]\n", pid, si->name);
+void soinfo::CallFunction(const char* function_name UNUSED, void (*function)()) {
+  if (function == NULL) {
+    return;
+  }
+
+  TRACE("[ %5d Calling %s @ %p for '%s' ]\n", pid, function_name, function, name);
+  function();
+  TRACE("[ %5d Done calling %s for '%s' ]\n", pid, function_name, name);
 }
 
-void soinfo_call_constructors(soinfo *si)
-{
-    if (si->constructors_called)
-        return;
+void soinfo::CallPreInitConstructors() {
+  CallArray("DT_PREINIT_ARRAY", preinit_array, preinit_array_count, false);
+}
 
-    // Set this before actually calling the constructors, otherwise it doesn't
-    // protect against recursive constructor calls. One simple example of
-    // constructor recursion is the libc debug malloc, which is implemented in
-    // libc_malloc_debug_leak.so:
-    // 1. The program depends on libc, so libc's constructor is called here.
-    // 2. The libc constructor calls dlopen() to load libc_malloc_debug_leak.so.
-    // 3. dlopen() calls soinfo_call_constructors() with the newly created
-    //    soinfo for libc_malloc_debug_leak.so.
-    // 4. The debug so depends on libc, so soinfo_call_constructors() is
-    //    called again with the libc soinfo. If it doesn't trigger the early-
-    //    out above, the libc constructor will be called again (recursively!).
-    si->constructors_called = 1;
+void soinfo::CallConstructors() {
+  if (constructors_called) {
+    return;
+  }
 
-    if (!(si->flags & FLAG_EXE) && si->preinit_array) {
-      DL_ERR("shared library \"%s\" has a preinit_array table @ 0x%08x. "
-          "This is INVALID.", si->name, (unsigned) si->preinit_array);
-    }
+  // We set constructors_called before actually calling the constructors, otherwise it doesn't
+  // protect against recursive constructor calls. One simple example of constructor recursion
+  // is the libc debug malloc, which is implemented in libc_malloc_debug_leak.so:
+  // 1. The program depends on libc, so libc's constructor is called here.
+  // 2. The libc constructor calls dlopen() to load libc_malloc_debug_leak.so.
+  // 3. dlopen() calls the constructors on the newly created
+  //    soinfo for libc_malloc_debug_leak.so.
+  // 4. The debug .so depends on libc, so CallConstructors is
+  //    called again with the libc soinfo. If it doesn't trigger the early-
+  //    out above, the libc constructor will be called again (recursively!).
+  constructors_called = true;
 
-    if (si->dynamic) {
-        unsigned *d;
-        for(d = si->dynamic; *d; d += 2) {
-            if(d[0] == DT_NEEDED){
-                soinfo* lsi = find_loaded_library(si->strtab + d[1]);
-                if (!lsi) {
-                    DL_ERR("\"%s\": could not initialize dependent library",
-                           si->name);
-                } else {
-                    soinfo_call_constructors(lsi);
-                }
-            }
+  if (!(flags & FLAG_EXE) && preinit_array) {
+    DL_ERR("shared library \"%s\" has a preinit_array table @ %p", name, preinit_array);
+    return;
+  }
+
+  if (dynamic) {
+    for (unsigned* d = dynamic; *d; d += 2) {
+      if (d[0] == DT_NEEDED) {
+        soinfo* lsi = find_loaded_library(strtab + d[1]);
+        if (lsi == NULL) {
+          DL_ERR("\"%s\": could not initialize dependent library", name);
+        } else {
+          lsi->CallConstructors();
         }
+      }
     }
+  }
 
-    if (si->init_func) {
-        TRACE("[ %5d Calling init_func @ 0x%08x for '%s' ]\n", pid,
-              (unsigned)si->init_func, si->name);
-        si->init_func();
-        TRACE("[ %5d Done calling init_func for '%s' ]\n", pid, si->name);
-    }
-
-    if (si->init_array) {
-        TRACE("[ %5d Calling init_array @ 0x%08x [%d] for '%s' ]\n", pid,
-              (unsigned)si->init_array, si->init_array_count, si->name);
-        call_array(si->init_array, si->init_array_count, 0);
-        TRACE("[ %5d Done calling init_array for '%s' ]\n", pid, si->name);
-    }
-
+  CallFunction("DT_INIT", init_func);
+  CallArray("DT_INIT_ARRAY", init_array, init_array_count, false);
 }
 
-static void call_destructors(soinfo *si)
-{
-    if (si->fini_array) {
-        TRACE("[ %5d Calling fini_array @ 0x%08x [%d] for '%s' ]\n", pid,
-              (unsigned)si->fini_array, si->fini_array_count, si->name);
-        call_array(si->fini_array, si->fini_array_count, 1);
-        TRACE("[ %5d Done calling fini_array for '%s' ]\n", pid, si->name);
-    }
-
-    if (si->fini_func) {
-        TRACE("[ %5d Calling fini_func @ 0x%08x for '%s' ]\n", pid,
-              (unsigned)si->fini_func, si->name);
-        si->fini_func();
-        TRACE("[ %5d Done calling fini_func for '%s' ]\n", pid, si->name);
-    }
+void soinfo::CallDestructors() {
+  CallArray("DT_FINI_ARRAY", fini_array, fini_array_count, true);
+  CallFunction("DT_FINI", fini_func);
 }
 
 /* Force any of the closed stdin, stdout and stderr to be associated with
@@ -1457,16 +1477,15 @@
     return return_value;
 }
 
-static int soinfo_link_image(soinfo *si)
-{
-    unsigned *d;
+static bool soinfo_link_image(soinfo* si) {
+    si->flags |= FLAG_ERROR;
+
     /* "base" might wrap around UINT32_MAX. */
     Elf32_Addr base = si->load_bias;
     const Elf32_Phdr *phdr = si->phdr;
     int phnum = si->phnum;
     int relocating_linker = (si->flags & FLAG_LINKER) != 0;
     soinfo **needed, **pneeded;
-    size_t dynamic_count;
 
     /* We can't debug anything until the linker is relocated */
     if (!relocating_linker) {
@@ -1476,13 +1495,14 @@
     }
 
     /* Extract dynamic section */
+    size_t dynamic_count;
     phdr_table_get_dynamic_section(phdr, phnum, base, &si->dynamic,
                                    &dynamic_count);
     if (si->dynamic == NULL) {
         if (!relocating_linker) {
-            DL_ERR("missing PT_DYNAMIC?!");
+            DL_ERR("missing PT_DYNAMIC in \"%s\"", si->name);
         }
-        goto fail;
+        return false;
     } else {
         if (!relocating_linker) {
             DEBUG("%5d dynamic = %p\n", pid, si->dynamic);
@@ -1495,7 +1515,7 @@
 #endif
 
     /* extract useful information from dynamic section */
-    for(d = si->dynamic; *d; d++){
+    for (unsigned* d = si->dynamic; *d; ++d) {
         DEBUG("%5d d = %p, d[0] = 0x%08x d[1] = 0x%08x\n", pid, d, d[0], d[1]);
         switch(*d++){
         case DT_HASH:
@@ -1512,8 +1532,8 @@
             break;
         case DT_PLTREL:
             if(*d != DT_REL) {
-                DL_ERR("DT_RELA not supported");
-                goto fail;
+                DL_ERR("unsupported DT_RELA in \"%s\"", si->name);
+                return false;
             }
             break;
         case DT_JMPREL:
@@ -1539,8 +1559,8 @@
 #endif
             break;
          case DT_RELA:
-            DL_ERR("DT_RELA not supported");
-            goto fail;
+            DL_ERR("unsupported DT_RELA in \"%s\"", si->name);
+            return false;
         case DT_INIT:
             si->init_func = (void (*)(void))(base + *d);
             DEBUG("%5d %s constructors (init func) found at %p\n",
@@ -1641,24 +1661,31 @@
     DEBUG("%5d si->base = 0x%08x, si->strtab = %p, si->symtab = %p\n",
            pid, si->base, si->strtab, si->symtab);
 
-    if((si->strtab == 0) || (si->symtab == 0)) {
-        DL_ERR("missing essential tables");
-        goto fail;
+    // Sanity checks.
+    if (si->nbucket == 0) {
+        DL_ERR("empty/missing DT_HASH in \"%s\" (built with --hash-style=gnu?)", si->name);
+        return false;
+    }
+    if (si->strtab == 0) {
+        DL_ERR("empty/missing DT_STRTAB in \"%s\"", si->name);
+        return false;
+    }
+    if (si->symtab == 0) {
+        DL_ERR("empty/missing DT_SYMTAB in \"%s\"", si->name);
+        return false;
     }
 
     /* if this is the main executable, then load all of the preloads now */
-    if(si->flags & FLAG_EXE) {
-        int i;
+    if (si->flags & FLAG_EXE) {
         memset(preloads, 0, sizeof(preloads));
-        for(i = 0; ldpreload_names[i] != NULL; i++) {
-            soinfo *lsi = find_library(ldpreload_names[i]);
-            if(lsi == 0) {
+        for (size_t i = 0; gLdPreloadNames[i] != NULL; i++) {
+            soinfo* lsi = find_library(gLdPreloadNames[i]);
+            if (lsi == NULL) {
                 strlcpy(tmp_err_buf, linker_get_error(), sizeof(tmp_err_buf));
                 DL_ERR("could not load library \"%s\" needed by \"%s\"; caused by %s",
-                       ldpreload_names[i], si->name, tmp_err_buf);
-                goto fail;
+                       gLdPreloadNames[i], si->name, tmp_err_buf);
+                return false;
             }
-            lsi->refcount++;
             preloads[i] = lsi;
         }
     }
@@ -1666,18 +1693,17 @@
     /* dynamic_count is an upper bound for the number of needed libs */
     pneeded = needed = (soinfo**) alloca((1 + dynamic_count) * sizeof(soinfo*));
 
-    for(d = si->dynamic; *d; d += 2) {
-        if(d[0] == DT_NEEDED){
+    for (unsigned* d = si->dynamic; *d; d += 2) {
+        if (d[0] == DT_NEEDED) {
             DEBUG("%5d %s needs %s\n", pid, si->name, si->strtab + d[1]);
-            soinfo *lsi = find_library(si->strtab + d[1]);
-            if(lsi == 0) {
+            soinfo* lsi = find_library(si->strtab + d[1]);
+            if (lsi == NULL) {
                 strlcpy(tmp_err_buf, linker_get_error(), sizeof(tmp_err_buf));
                 DL_ERR("could not load library \"%s\" needed by \"%s\"; caused by %s",
                        si->strtab + d[1], si->name, tmp_err_buf);
-                goto fail;
+                return false;
             }
             *pneeded++ = lsi;
-            lsi->refcount++;
         }
     }
     *pneeded = NULL;
@@ -1691,24 +1717,26 @@
         if (phdr_table_unprotect_segments(si->phdr, si->phnum, si->load_bias) < 0) {
             DL_ERR("can't unprotect loadable segments for \"%s\": %s",
                    si->name, strerror(errno));
-            goto fail;
+            return false;
         }
     }
 
-    if(si->plt_rel) {
+    if (si->plt_rel) {
         DEBUG("[ %5d relocating %s plt ]\n", pid, si->name );
-        if(soinfo_relocate(si, si->plt_rel, si->plt_rel_count, needed))
-            goto fail;
+        if(soinfo_relocate(si, si->plt_rel, si->plt_rel_count, needed)) {
+            return false;
+        }
     }
-    if(si->rel) {
+    if (si->rel) {
         DEBUG("[ %5d relocating %s ]\n", pid, si->name );
-        if(soinfo_relocate(si, si->rel, si->rel_count, needed))
-            goto fail;
+        if(soinfo_relocate(si, si->rel, si->rel_count, needed)) {
+            return false;
+        }
     }
 
 #ifdef ANDROID_MIPS_LINKER
-    if(mips_relocate_got(si, needed)) {
-        goto fail;
+    if (mips_relocate_got(si, needed)) {
+        return false;
     }
 #endif
 
@@ -1721,7 +1749,7 @@
         if (phdr_table_protect_segments(si->phdr, si->phnum, si->load_bias) < 0) {
             DL_ERR("can't protect segments for \"%s\": %s",
                    si->name, strerror(errno));
-            goto fail;
+            return false;
         }
     }
 
@@ -1729,25 +1757,17 @@
     if (phdr_table_protect_gnu_relro(si->phdr, si->phnum, si->load_bias) < 0) {
         DL_ERR("can't enable GNU RELRO protection for \"%s\": %s",
                si->name, strerror(errno));
-        goto fail;
+        return false;
     }
 
-    /* If this is a SET?ID program, dup /dev/null to opened stdin,
-       stdout and stderr to close a security hole described in:
-
-    ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
-
-     */
+    // If this is a setuid/setgid program, close the security hole described in
+    // ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
     if (get_AT_SECURE()) {
         nullify_closed_stdio();
     }
     notify_gdb_of_load(si);
-    return 0;
-
-fail:
-    ERROR("failed to link %s\n", si->name);
-    si->flags |= FLAG_ERROR;
-    return -1;
+    si->flags &= ~FLAG_ERROR;
+    return true;
 }
 
 static void parse_path(const char* path, const char* delimiters,
@@ -1777,14 +1797,14 @@
 }
 
 static void parse_LD_LIBRARY_PATH(const char* path) {
-    parse_path(path, ":", ldpaths,
-               ldpaths_buf, sizeof(ldpaths_buf), LDPATH_MAX);
+    parse_path(path, ":", gLdPaths,
+               gLdPathsBuffer, sizeof(gLdPathsBuffer), LDPATH_MAX);
 }
 
 static void parse_LD_PRELOAD(const char* path) {
     // We have historically supported ':' as well as ' ' in LD_PRELOAD.
-    parse_path(path, " :", ldpreload_names,
-               ldpreloads_buf, sizeof(ldpreloads_buf), LDPRELOAD_MAX);
+    parse_path(path, " :", gLdPreloadNames,
+               gLdPreloadsBuffer, sizeof(gLdPreloadsBuffer), LDPRELOAD_MAX);
 }
 
 /*
@@ -1924,17 +1944,17 @@
 
     somain = si;
 
-    if(soinfo_link_image(si)) {
+    if (!soinfo_link_image(si)) {
         char errmsg[] = "CANNOT LINK EXECUTABLE\n";
         write(2, __linker_dl_err_buf, strlen(__linker_dl_err_buf));
         write(2, errmsg, sizeof(errmsg));
         exit(EXIT_FAILURE);
     }
 
-    soinfo_call_preinit_constructors(si);
+    si->CallPreInitConstructors();
 
     for (size_t i = 0; preloads[i] != NULL; ++i) {
-        soinfo_call_constructors(preloads[i]);
+        preloads[i]->CallConstructors();
     }
 
     /*After the link_image, the si->base is initialized.
@@ -1943,7 +1963,7 @@
      *for some arch like x86 could work correctly within so exe.
      */
     map->l_addr = si->base;
-    soinfo_call_constructors(si);
+    si->CallConstructors();
 
 #if TIMING
     gettimeofday(&t1,NULL);
@@ -2063,7 +2083,7 @@
     linker_so.phnum = elf_hdr->e_phnum;
     linker_so.flags |= FLAG_LINKER;
 
-    if (soinfo_link_image(&linker_so)) {
+    if (!soinfo_link_image(&linker_so)) {
         // It would be nice to print an error message, but if the linker
         // can't link itself, there's no guarantee that we'll be able to
         // call write() (because it involves a GOT reference).
@@ -2077,6 +2097,8 @@
     // the main part of the linker now.
     unsigned start_address = __linker_init_post_relocation(elfdata, linker_addr);
 
+    set_soinfo_pool_protection(PROT_READ);
+
     // Return the address that the calling assembly stub should jump to.
     return start_address;
 }
diff --git a/linker/linker.h b/linker/linker.h
index cb33602..51869e7 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -36,54 +36,39 @@
 
 #include <link.h>
 
-#undef PAGE_MASK
-#undef PAGE_SIZE
-#define PAGE_SIZE 4096
-#define PAGE_MASK (PAGE_SIZE-1)
+// Returns the address of the page containing address 'x'.
+#define PAGE_START(x)  ((x) & PAGE_MASK)
 
-/* Convenience macros to make page address/offset computations more explicit */
+// Returns the offset of address 'x' in its page.
+#define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
 
-/* Returns the address of the page starting at address 'x' */
-#define PAGE_START(x)  ((x) & ~PAGE_MASK)
-
-/* Returns the offset of address 'x' in its memory page, i.e. this is the
- * same than 'x' - PAGE_START(x) */
-#define PAGE_OFFSET(x) ((x) & PAGE_MASK)
-
-/* Returns the address of the next page after address 'x', unless 'x' is
- * itself at the start of a page. Equivalent to:
- *
- *  (x == PAGE_START(x)) ? x : PAGE_START(x)+PAGE_SIZE
- */
+// Returns the address of the next page after address 'x', unless 'x' is
+// itself at the start of a page.
 #define PAGE_END(x)    PAGE_START((x) + (PAGE_SIZE-1))
 
-void debugger_init();
+// Magic shared structures that GDB knows about.
 
-/* magic shared structures that GDB knows about */
-
-struct link_map
-{
-    uintptr_t l_addr;
-    char * l_name;
-    uintptr_t l_ld;
-    struct link_map * l_next;
-    struct link_map * l_prev;
+struct link_map {
+  uintptr_t l_addr;
+  char * l_name;
+  uintptr_t l_ld;
+  struct link_map * l_next;
+  struct link_map * l_prev;
 };
 
 // Values for r_debug->state
 enum {
-    RT_CONSISTENT,
-    RT_ADD,
-    RT_DELETE
+  RT_CONSISTENT,
+  RT_ADD,
+  RT_DELETE
 };
 
-struct r_debug
-{
-    int32_t r_version;
-    struct link_map * r_map;
-    void (*r_brk)(void);
-    int32_t r_state;
-    uintptr_t r_ldbase;
+struct r_debug {
+  int32_t r_version;
+  struct link_map* r_map;
+  void (*r_brk)(void);
+  int32_t r_state;
+  uintptr_t r_ldbase;
 };
 
 #define FLAG_LINKED     0x00000001
@@ -94,83 +79,87 @@
 #define SOINFO_NAME_LEN 128
 
 struct soinfo {
-    char name[SOINFO_NAME_LEN];
-    const Elf32_Phdr *phdr;
-    int phnum;
-    unsigned entry;
-    unsigned base;
-    unsigned size;
+  char name[SOINFO_NAME_LEN];
+  const Elf32_Phdr* phdr;
+  int phnum;
+  unsigned entry;
+  unsigned base;
+  unsigned size;
 
-    int unused;  // DO NOT USE, maintained for compatibility.
+  int unused;  // DO NOT USE, maintained for compatibility.
 
-    unsigned *dynamic;
+  unsigned* dynamic;
 
-    unsigned unused2; // DO NOT USE, maintained for compatibility
-    unsigned unused3; // DO NOT USE, maintained for compatibility
+  unsigned unused2; // DO NOT USE, maintained for compatibility
+  unsigned unused3; // DO NOT USE, maintained for compatibility
 
-    soinfo *next;
-    unsigned flags;
+  soinfo* next;
+  unsigned flags;
 
-    const char *strtab;
-    Elf32_Sym *symtab;
+  const char* strtab;
+  Elf32_Sym* symtab;
 
-    unsigned nbucket;
-    unsigned nchain;
-    unsigned *bucket;
-    unsigned *chain;
+  unsigned nbucket;
+  unsigned nchain;
+  unsigned* bucket;
+  unsigned* chain;
 
-    unsigned *plt_got;
+  unsigned* plt_got;
 
-    Elf32_Rel *plt_rel;
-    unsigned plt_rel_count;
+  Elf32_Rel* plt_rel;
+  unsigned plt_rel_count;
 
-    Elf32_Rel *rel;
-    unsigned rel_count;
+  Elf32_Rel* rel;
+  unsigned rel_count;
 
-    unsigned *preinit_array;
-    unsigned preinit_array_count;
+  unsigned* preinit_array;
+  unsigned preinit_array_count;
 
-    unsigned *init_array;
-    unsigned init_array_count;
-    unsigned *fini_array;
-    unsigned fini_array_count;
+  unsigned* init_array;
+  unsigned init_array_count;
+  unsigned* fini_array;
+  unsigned fini_array_count;
 
-    void (*init_func)(void);
-    void (*fini_func)(void);
+  void (*init_func)();
+  void (*fini_func)();
 
 #if defined(ANDROID_ARM_LINKER)
-    /* ARM EABI section used for stack unwinding. */
-    unsigned *ARM_exidx;
-    unsigned ARM_exidx_count;
+  // ARM EABI section used for stack unwinding.
+  unsigned* ARM_exidx;
+  unsigned ARM_exidx_count;
 #elif defined(ANDROID_MIPS_LINKER)
 #if 0
-     /* not yet */
-     unsigned *mips_pltgot
+  // Not yet.
+  unsigned* mips_pltgot
 #endif
-     unsigned mips_symtabno;
-     unsigned mips_local_gotno;
-     unsigned mips_gotsym;
-#endif /* ANDROID_*_LINKER */
+  unsigned mips_symtabno;
+  unsigned mips_local_gotno;
+  unsigned mips_gotsym;
+#endif
 
-    unsigned refcount;
-    struct link_map linkmap;
+  unsigned refcount;
+  struct link_map linkmap;
 
-    int constructors_called;
+  bool constructors_called;
 
-    /* When you read a virtual address from the ELF file, add this
-     * value to get the corresponding address in the process' address space */
-    Elf32_Addr load_bias;
+  // When you read a virtual address from the ELF file, add this
+  // value to get the corresponding address in the process' address space.
+  Elf32_Addr load_bias;
 
-    bool has_text_relocations;
-    bool has_DT_SYMBOLIC;
+  bool has_text_relocations;
+  bool has_DT_SYMBOLIC;
+
+  void CallConstructors();
+  void CallDestructors();
+  void CallPreInitConstructors();
+
+ private:
+  void CallArray(const char* array_name, unsigned* array, int count, bool reverse);
+  void CallFunction(const char* function_name, void (*function)());
 };
 
-
 extern soinfo libdl_info;
 
-
-#include <asm/elf.h>
-
 #if defined(ANDROID_ARM_LINKER)
 
 // These aren't defined in <arch-arm/asm/elf.h>.
@@ -218,16 +207,17 @@
 #define DT_PREINIT_ARRAYSZ 33
 #endif
 
-soinfo *find_library(const char *name);
-Elf32_Sym *lookup(const char *name, soinfo **found, soinfo *start);
-soinfo *find_containing_library(const void *addr);
-const char *linker_get_error(void);
+soinfo* do_dlopen(const char* name);
+int do_dlclose(soinfo* si);
 
-int soinfo_unload(soinfo* si);
-Elf32_Sym *soinfo_find_symbol(soinfo* si, const void *addr);
-Elf32_Sym *soinfo_lookup(soinfo *si, const char *name);
-void soinfo_call_constructors(soinfo *si);
+Elf32_Sym* lookup(const char* name, soinfo** found, soinfo* start);
+soinfo* find_containing_library(const void* addr);
+const char* linker_get_error();
 
+Elf32_Sym* soinfo_find_symbol(soinfo* si, const void* addr);
+Elf32_Sym* soinfo_lookup(soinfo* si, const char* name);
+
+void debugger_init();
 extern "C" void notify_gdb_of_libraries();
 
 #endif
diff --git a/tests/Android.mk b/tests/Android.mk
index 68dee10..9d5cd36 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -62,6 +62,21 @@
 LOCAL_STATIC_LIBRARIES += libstlport_static libstdc++ libm libc
 include $(BUILD_NATIVE_TEST)
 
+
+
+
+# Build no-elf-hash-table-library.so to test dlopen(3) on a library that
+# only has a GNU-style hash table.
+include $(CLEAR_VARS)
+LOCAL_MODULE := no-elf-hash-table-library
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_SRC_FILES := empty.cpp
+LOCAL_LDFLAGS := -Wl,--hash-style=gnu
+include $(BUILD_SHARED_LIBRARY)
+
+
+
+
 # Build for the host (with glibc).
 # Note that this will build against glibc, so it's not useful for testing
 # bionic's implementation, but it does let you use glibc as a reference
diff --git a/tests/dlopen_test.cpp b/tests/dlopen_test.cpp
index d38d8c5..794fb97 100644
--- a/tests/dlopen_test.cpp
+++ b/tests/dlopen_test.cpp
@@ -46,6 +46,8 @@
   gCalled = false;
   function();
   ASSERT_TRUE(gCalled);
+
+  ASSERT_EQ(0, dlclose(self));
 }
 
 TEST(dlopen, dlopen_failure) {
@@ -108,6 +110,8 @@
   sym = dlsym(self, "ThisSymbolDoesNotExist");
   ASSERT_TRUE(sym == NULL);
   ASSERT_SUBSTR("undefined symbol: ThisSymbolDoesNotExist", dlerror());
+
+  ASSERT_EQ(0, dlclose(self));
 }
 
 TEST(dlopen, dladdr) {
@@ -166,6 +170,8 @@
 
   // The base address should be the address we were loaded at.
   ASSERT_EQ(info.dli_fbase, base_address);
+
+  ASSERT_EQ(0, dlclose(self));
 }
 
 TEST(dlopen, dladdr_invalid) {
@@ -181,3 +187,13 @@
   ASSERT_EQ(dladdr(&info, &info), 0); // Zero on error, non-zero on success.
   ASSERT_TRUE(dlerror() == NULL); // dladdr(3) doesn't set dlerror(3).
 }
+
+#if __BIONIC__
+// Our dynamic linker doesn't support GNU hash tables.
+TEST(dlopen, library_with_only_gnu_hash) {
+  dlerror(); // Clear any pending errors.
+  void* handle = dlopen("empty-library.so", RTLD_NOW);
+  ASSERT_TRUE(handle == NULL);
+  ASSERT_STREQ("dlopen failed: empty/missing DT_HASH in \"empty-library.so\" (built with --hash-style=gnu?)", dlerror());
+}
+#endif
diff --git a/tests/empty.cpp b/tests/empty.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/empty.cpp
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index e400b84..da945b4 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -109,3 +109,20 @@
   void* result;
   ASSERT_EQ(EDEADLK, pthread_join(pthread_self(), &result));
 }
+
+#if __BIONIC__ // For some reason, gtest on bionic can cope with this but gtest on glibc can't.
+
+static void TestBug37410() {
+  pthread_t t1;
+  ASSERT_EQ(0, pthread_create(&t1, NULL, JoinFn, reinterpret_cast<void*>(pthread_self())));
+  pthread_exit(NULL);
+}
+
+// We have to say "DeathTest" here so gtest knows to run this test (which exits)
+// in its own process.
+TEST(pthread_DeathTest, pthread_bug_37410) {
+  // http://code.google.com/p/android/issues/detail?id=37410
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  EXPECT_EXIT(TestBug37410(), ::testing::ExitedWithCode(0), "");
+}
+#endif