diff options
61 files changed, 563 insertions, 4328 deletions
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 @@ int __system_properties_init(void); * 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]; - - /* 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_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); - - tls_area[TLS_SLOT_BIONIC_PREINIT] = elfdata; -} +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; + + pthread_attr_t thread_attr; + pthread_attr_init(&thread_attr); + pthread_attr_setstack(&thread_attr, (void*) stack_bottom, stack_size); -void __libc_init_common(uintptr_t *elfdata) -{ - int argc = *elfdata; - char** argv = (char**)(elfdata + 1); - char** envp = argv + argc + 1; + static pthread_internal_t thread; + _init_thread(&thread, gettid(), &thread_attr, (void*) stack_bottom, false); - /* get the initial thread from TLS and add it to gThreadList */ - _pthread_internal_add(__get_thread()); + static void* tls_area[BIONIC_TLS_SLOTS]; + __init_tls(tls_area, &thread); + tls_area[TLS_SLOT_BIONIC_PREINIT] = elf_data; +} - /* clear errno */ - errno = 0; +void __libc_init_common(uintptr_t* elf_data) { + int argc = *elf_data; + char** argv = (char**) (elf_data + 1); + char** envp = argv + argc + 1; - /* set program name */ - __progname = argv[0] ? argv[0] : "<unknown>"; + // 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); - /* setup environment pointer */ - environ = envp; + // Set various globals. + errno = 0; + __progname = argv[0] ? argv[0] : "<unknown>"; + 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 @@ void __libc_init_common(uintptr_t *elfdata) * '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 */ - - /* Sanity check - first entry must be -1 */ - if (array == NULL || (size_t)fini_array[0] != minus1) { - return; +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; + } + + /* 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_internal_t* gThreadList = NULL; 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 @@ int pthread_create(pthread_t *thread_out, pthread_attr_t const * attr, if (thread == NULL) { return ENOMEM; } + thread->allocated_on_heap = true; if (attr == NULL) { attr = &gDefaultPthreadAttr; @@ -323,7 +321,7 @@ int pthread_create(pthread_t *thread_out, pthread_attr_t const * attr, 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 @@ int pthread_create(pthread_t *thread_out, pthread_attr_t const * attr, 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 @@ void pthread_exit(void * retval) // 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 @@ FoundIt: */ 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 @@ __BEGIN_DECLS 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 @@ typedef __uint32_t fexcept_t; #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 @@ typedef __uint32_t fexcept_t; #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 @@ const char* dlerror() { 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 dladdr(const void* addr, Dl_info* info) { 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 @@ soinfo libdl_info = { 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 gLdPathsBuffer[LDPATH_BUFSIZE]; +static const char* gLdPaths[LDPATH_MAX + 1]; -static char ldpreloads_buf[LDPRELOAD_BUFSIZE]; -static const char *ldpreload_names[LDPRELOAD_MAX + 1]; +static char gLdPreloadsBuffer[LDPRELOAD_BUFSIZE]; +static const char* gLdPreloadNames[LDPRELOAD_MAX + 1]; static soinfo *preloads[LDPRELOAD_MAX + 1]; @@ -257,38 +263,65 @@ void notify_gdb_of_libraries() { 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; + } - /* 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; + // 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. } + } +} - soinfo* si = freelist; - freelist = freelist->next; +static soinfo* soinfo_alloc(const char* name) { + if (strlen(name) >= SOINFO_NAME_LEN) { + DL_ERR("library name \"%s\" too long", 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; + if (!ensure_free_list_non_empty()) { + DL_ERR("out of memory when loading \"%s\"", name); + return NULL; + } - TRACE("%5d name %s: allocated soinfo @ %p\n", pid, name, si); - return si; + // Take the head element off the free list. + soinfo* si = gSoInfoFreeList; + gSoInfoFreeList = gSoInfoFreeList->next; + + // 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 @@ static void soinfo_free(soinfo* si) */ 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 @@ static void dump(soinfo *si) } #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; + } + int fd = TEMP_FAILURE_RETRY(open(buf, O_RDONLY | O_CLOEXEC)); + if (fd != -1) { + return fd; } - return TEMP_FAILURE_RETRY(open(name, O_RDONLY)); + } + return -1; } -static int open_library(const char *name) -{ - int fd; - char buf[512]; - const char * const*path; - int n; - - TRACE("[ %5d opening %s ]\n", pid, name); +static int open_library(const char* 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; - } - 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; + // 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; } + // ...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 @@ struct phdr_ptr { 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 @@ static soinfo* load_library(const char* name) 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 @@ static soinfo *find_loaded_library(const char *name) return NULL; } -soinfo *find_library(const char *name) -{ - soinfo *si; +static soinfo* find_library_internal(const char* name) { + if (name == NULL) { + return somain; + } + + 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; + } - if (name == NULL) - return somain; + TRACE("[ %5d '%s' has not been loaded yet. Locating...]\n", pid, name); + si = load_library(name); + if (si != NULL) { + si = init_library(si); + } - si = find_loaded_library(name); - if (si != NULL) { - if(si->flags & FLAG_ERROR) { - DL_ERR("\"%s\" failed to load previously", name); - return NULL; + return si; +} + +static soinfo* find_library(const char* name) { + soinfo* si = find_library_internal(name); + if (si != NULL) { + si->refcount++; + } + return 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 != 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); } - 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); + 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; } -static void call_destructors(soinfo *si); - -int soinfo_unload(soinfo* si) { - if (si->refcount == 1) { - TRACE("%5d unloading '%s'\n", pid, si->name); - call_destructors(si); - - 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); - } - } - } +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; +} - 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; +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 @@ static int mips_relocate_got(soinfo* si, soinfo* needed[]) { * * 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; + } + + int step = 1; + if (reverse) { + array += (count-1); + step = -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(); + } + + TRACE("[ %5d Done calling %s for '%s' ]\n", pid, array_name, name); +} -static void call_array(unsigned *ctor, int count, int reverse) -{ - int n, inc = 1; - - if (reverse) { - ctor += (count-1); - inc = -1; - } +void soinfo::CallFunction(const char* function_name UNUSED, void (*function)()) { + if (function == NULL) { + return; + } - 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 Calling %s @ %p for '%s' ]\n", pid, function_name, function, name); + function(); + TRACE("[ %5d Done calling %s for '%s' ]\n", pid, function_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::CallPreInitConstructors() { + CallArray("DT_PREINIT_ARRAY", preinit_array, preinit_array_count, false); } -void soinfo_call_constructors(soinfo *si) -{ - if (si->constructors_called) - return; - - // 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; - - 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); - } - - 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); - } - } +void soinfo::CallConstructors() { + if (constructors_called) { + return; + } + + // 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 (!(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 @@ static int nullify_closed_stdio() { 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 @@ static int soinfo_link_image(soinfo *si) } /* 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 @@ static int soinfo_link_image(soinfo *si) #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 @@ static int soinfo_link_image(soinfo *si) 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 @@ static int soinfo_link_image(soinfo *si) #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 @@ static int soinfo_link_image(soinfo *si) 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 @@ static int soinfo_link_image(soinfo *si) /* 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 @@ static int soinfo_link_image(soinfo *si) 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 @@ static int soinfo_link_image(soinfo *si) 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 @@ static int soinfo_link_image(soinfo *si) 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_path(const char* path, const char* delimiters, } 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 @@ static unsigned __linker_init_post_relocation(unsigned **elfdata, unsigned linke 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 @@ static unsigned __linker_init_post_relocation(unsigned **elfdata, unsigned linke *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 @@ extern "C" unsigned __linker_init(unsigned **elfdata) { 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 @@ extern "C" unsigned __linker_init(unsigned **elfdata) { // 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,82 +79,86 @@ struct r_debug #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 - unsigned mips_symtabno; - unsigned mips_local_gotno; - unsigned mips_gotsym; -#endif /* ANDROID_*_LINKER */ - - unsigned refcount; - struct link_map linkmap; - int constructors_called; + unsigned refcount; + struct link_map linkmap; - /* 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 constructors_called; - bool has_text_relocations; - bool has_DT_SYMBOLIC; -}; + // 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; -extern soinfo libdl_info; + 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)()); +}; -#include <asm/elf.h> +extern soinfo libdl_info; #if defined(ANDROID_ARM_LINKER) @@ -218,16 +207,17 @@ extern soinfo libdl_info; #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); + +Elf32_Sym* lookup(const char* name, soinfo** found, soinfo* start); +soinfo* find_containing_library(const void* addr); +const char* linker_get_error(); -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* 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_SRC_FILES := $(test_src_files) 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 @@ TEST(dlopen, dlsym_in_self) { gCalled = false; function(); ASSERT_TRUE(gCalled); + + ASSERT_EQ(0, dlclose(self)); } TEST(dlopen, dlopen_failure) { @@ -108,6 +110,8 @@ TEST(dlopen, dlsym_failures) { 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 @@ TEST(dlopen, dladdr) { // 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 @@ TEST(dlopen, dladdr_invalid) { 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 @@ TEST(pthread, pthread_join_self) { 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 |
