Add Sortix Math Library.

This work is based in part on code from NetBSD libm, libc and kernel.

The library is partly public domain and partly BSD-style licensed.
This commit is contained in:
Jonas 'Sortie' Termansen 2013-01-16 03:07:59 +01:00
parent 14c32c3433
commit 5980be9b3c
475 changed files with 33962 additions and 92 deletions

View File

@ -3,7 +3,7 @@ MAKEFILE_NOT_MEANT_FOR_SORTIX=1
include compiler.mak
include version.mak
MODULES=libc dispd games mkinitrd mxmpp utils bench sortix
MODULES=libc libm dispd games mkinitrd mxmpp utils bench sortix
ifndef SYSROOT
SYSROOT:=$(shell pwd)/sysroot
@ -60,7 +60,7 @@ sysroot-fsh:
.PHONY: sysroot-base-headers
sysroot-base-headers: sysroot-fsh
(for D in libc sortix; do ($(MAKE) -C $$D install-headers $(SUBMAKE_OPTIONS) DESTDIR="$(SYSROOT)") || exit $$?; done)
(for D in libc libm sortix; do ($(MAKE) -C $$D install-headers $(SUBMAKE_OPTIONS) DESTDIR="$(SYSROOT)") || exit $$?; done)
.PHONY: sysroot-system
sysroot-system: sysroot-fsh sysroot-base-headers

View File

@ -25,7 +25,6 @@ dirent/alphasort.o \
dirent/dir.o \
dirent/versionsort.o \
errno/errno.o \
fabs.o \
signal/sigaddset.o \
signal/sigdelset.o \
signal/sigemptyset.o \
@ -429,7 +428,7 @@ ifeq ($(HOST),x86_64-sortix)
SORTIXFLAGS:=$(SORTIXFLAGS) -mno-red-zone
endif
BINS=libc.a libg.a libm.a libpthread.a libstdc++.a $(CRTOBJ)
BINS=libc.a libg.a libpthread.a libstdc++.a $(CRTOBJ)
BINSKERNEL=libc-sortix.a
INSTALLLIBS:=$(addprefix $(DESTDIR)$(LIBDIR)/,$(BINS))
INSTALLLIBSKERNEL:=$(addprefix $(DESTDIR)$(LIBDIR)/,$(BINSKERNEL))
@ -454,9 +453,6 @@ libc-sortix.a: $(SORTIXOBJS)
libg.a:
$(HOSTAR) rcs $@
libm.a:
$(HOSTAR) rcs $@
libpthread.a:
$(HOSTAR) rcs $@

View File

@ -1,46 +0,0 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012.
This file is part of the Sortix C Library.
The Sortix C Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
The Sortix C Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
fabs.cpp
Absolute value of floating point numbers.
*******************************************************************************/
#include <math.h>
extern "C" double fabs(double x)
{
if ( x < 0.0f )
return -x;
return x;
}
extern "C" float fabsf(float x)
{
if ( x < 0.0f )
return -x;
return x;
}
extern "C" long double fabsl(long double x)
{
if ( x < 0.0f )
return -x;
return x;
}

View File

@ -1,39 +0,0 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
This file is part of the Sortix C Library.
The Sortix C Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
The Sortix C Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see <http://www.gnu.org/licenses/>.
math.h
Mathematical declarations.h
*******************************************************************************/
#ifndef _MATH_H
#define _MATH_H 1
#include <features.h>
__BEGIN_DECLS
/* TODO: Actually comply with standards by declaring stuff here. */
double fabs(double x);
float fabsf(float x);
long double fabsl(long double x);
__END_DECLS
#endif

4
libm/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*.o
*.a
/*.o
/*.a

224
libm/LEGAL Normal file
View File

@ -0,0 +1,224 @@
Legal Information
=================
The Sortix Math Library (libm) is based on the NetBSD Math Library, with pieces
taken from the NetBSD C library and kernel. The upstream sources were adapted
for inclusion into the Sortix operating system. The library itself is licensed
under various BSD-style licenses with some parts in the public domain. Almost
all files have proper copyright notices that describe their license and who the
copyright belongs to. The few files that do not contain such explicit notices
are likely NetBSD-licensed as the files originate come from that project.
This library is licensed under the following licenses.
Public Domain
-------------
The public domain files usually contains statements such as:
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
This may be slightly problematic as the concept of public domain doesn't exist
in all jurisdictions.
Winning Strategies
------------------
A few files currently still contain advertisement clauses. In particular, these
files require attribution of Winning Strategies:
* arch/i387/e_exp.S
* arch/x86_64/e_exp.S
However, the author of those files have released a lot of similar files into the
public domain that once had this license. It's likely that these files were
overlooked when the license was changed and their license was changed as well.
University of California License
--------------------------------
Some of the files originate back from the Berkeley Software Distribution (BSD).
These originally contained the advertisement clause, which was deleted entirely
in 1999 by the university. The license for these files today is something like:
/*-
* Copyright (c) 1990 The Regents of the University of California.
* 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.
* 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
* @(#)asm.h 5.5 (Berkeley) 5/7/91
*/
Lawrence Berkeley Laboratory
----------------------------
A few files contain the above University of California License as well as this
additional statement
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
Historically, the files that contained this statement also had another
advertisement statement, but these were deleted in the NetBSD sources.
SunPro License
--------------
A lot of files were developed by SunPro and bear this permissive license:
/*
* ====================================================
* 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.
* ====================================================
*/
CMU License
-----------
The file src/modf_ieee754.c has the following license:
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
The wording of the last clause is a bit worrying, as I am not sure whether it is
a requirement or whether granting such rights is optional. Perhaps this file
should be replaced.
NetBSD License
--------------
A lot of the files originate from the NetBSD project and bear its standard
license (Simplified BSD License). These files contain statements much like this:
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Klaus Klein.
*
* 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 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.
*/
A few files that was copied from upstream NetBSD bear no license but contain
the usual $NetBSD revision control tag - those can probably be assumed to be
under this license.
Other BSD-Licenses
------------------
A few files are BSD-style licensed, but don't originate with NetBSD. The license
is identical to the NetBSD license in almost every case. These files are
copyrighted by:
* David Schultz
* Steven G. Kargl
* Matthias Drochner
Sortix Math Library License
---------------------------
The library was modified to adapt it to the Sortix operating system. These
changes were intended to be licensed like the rest of the library, and so the
license is identical to the NetBSD license:
/*-
* Copyright (c) 2013 Jonas 'Sortie' Termansen.
* 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 ``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 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.
*/

416
libm/Makefile Normal file
View File

@ -0,0 +1,416 @@
include ../platform.mak
include ../compiler.mak
include ../version.mak
include ../dirs.mak
OPTLEVEL?=-O2 -g
CFLAGS?=$(OPTLEVEL)
# TODO: Better detection of the proper subdirectory here!
ifneq ($(shell echo $(HOST) | grep -E ^i[012346789]*86-),)
ARCH_SUBDIR:=arch/i387
ARCH_MACHINE_HEADERS:=$(ARCH_SUBDIR)/machine/npx.h
endif
ifneq ($(shell echo $(HOST) | grep -E ^x86_64-),)
ARCH_SUBDIR:=arch/x86_64
ARCH_MACHINE_HEADERS:=$(ARCH_SUBDIR)/machine/fpu.h
endif
ARCH_MACHINE_HEADERS:=$(ARCH_MACHINE_HEADERS) $(ARCH_SUBDIR)/machine/fenv.h
ARCH_SRCS=\
e_acos.S \
e_asin.S \
e_atan2.S \
e_expf.S \
e_exp.S \
e_fmod.S \
e_log10f.S \
e_log10.S \
e_log2f.S \
e_log2.S \
e_logf.S \
e_log.S \
e_remainderf.S \
e_remainder.S \
e_scalbf.S \
e_scalb.S \
e_sqrtf.S \
e_sqrt.S \
fabs.S \
fenv.c \
flt_rounds.S \
fpgetmask.S \
fpgetprec.S \
fpgetround.S \
fpgetsticky.S \
fpsetmask.S \
fpsetprec.S \
fpsetround.S \
fpsetsticky.S \
lrint.S \
s_atanf.S \
s_atan.S \
s_ceilf.S \
s_ceil.S \
s_copysignf.S \
s_copysign.S \
s_cosf.S \
s_cos.S \
s_finitef.S \
s_finite.S \
s_floorf.S \
s_floor.S \
s_ilogbf.S \
s_ilogbl.S \
s_ilogb.S \
s_log1pf.S \
s_log1p.S \
s_logbf.S \
s_logbl.S \
s_logb.S \
s_rintf.S \
s_rint.S \
s_scalbnf.S \
s_scalbn.S \
s_significandf.S \
s_significand.S \
s_sinf.S \
s_sin.S \
s_tanf.S \
s_tan.S \
COMMON_SRCS+=\
b_exp.c \
b_log.c \
b_tgamma.c \
compat_frexp_ieee754.c \
compat_ldexp_ieee754.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_hypot.c \
e_hypotf.c \
e_j0.c \
e_j0f.c \
e_j1.c \
e_j1f.c \
e_jn.c \
e_jnf.c \
e_lgammaf_r.c \
e_lgamma_r.c \
e_log10.c \
e_log10f.c \
e_log2.c \
e_log2f.c \
e_log.c \
e_logf.c \
e_pow.c \
e_powf.c \
e_remainder.c \
e_remainderf.c \
e_rem_pio2.c \
e_rem_pio2f.c \
e_scalb.c \
e_scalbf.c \
e_sinh.c \
e_sinhf.c \
e_sqrt.c \
e_sqrtf.c \
fpclassifyd_ieee754.c \
fpclassifyf_ieee754.c \
fpclassifyl.c \
fpclassifyl_ieee754.c \
isfinited_ieee754.c \
isfinitef_ieee754.c \
isfinitel.c \
isfinitel_ieee754.c \
isinfd_ieee754.c \
isinff_ieee754.c \
isinfl.c \
isinfl_ieee754.c \
isnand_ieee754.c \
isnanf_ieee754.c \
isnanl.c \
isnanl_ieee754.c \
k_cos.c \
k_cosf.c \
k_rem_pio2.c \
k_rem_pio2f.c \
k_sin.c \
k_sinf.c \
k_standard.c \
k_tan.c \
k_tanf.c \
llrint.c \
llrintf.c \
llround.c \
llroundf.c \
lrint.c \
lrintf.c \
lround.c \
lroundf.c \
modf_ieee754.c \
nan.c \
nanf.c \
nanl.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_copysign.c \
s_copysignf.c \
s_copysignl.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_fabsl.c \
s_fdim.c \
s_finite.c \
s_finitef.c \
s_floor.c \
s_floorf.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 \
signbitd_ieee754.c \
signbitf_ieee754.c \
signbitl.c \
s_ilogb.c \
s_ilogbf.c \
s_ilogbl.c \
s_isinff.c \
s_isnanf.c \
s_ldexp.c \
s_ldexpf.c \
s_lib_version.c \
s_log1p.c \
s_log1pf.c \
s_logb.c \
s_logbf.c \
s_logbl.c \
s_matherr.c \
s_modf.c \
s_modff.c \
s_nextafter.c \
s_nextafterf.c \
s_nextafterl.c \
s_nexttoward.c \
s_remquo.c \
s_remquof.c \
s_rint.c \
s_rintf.c \
s_round.c \
s_roundf.c \
s_scalbn.c \
s_scalbnf.c \
s_scalbnl.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_tgammaf.c \
s_trunc.c \
s_truncf.c \
w_acos.c \
w_acosf.c \
w_acosh.c \
w_acoshf.c \
w_asin.c \
w_asinf.c \
w_atan2.c \
w_atan2f.c \
w_atanh.c \
w_atanhf.c \
w_cosh.c \
w_coshf.c \
w_drem.c \
w_dremf.c \
w_exp.c \
w_expf.c \
w_fmod.c \
w_fmodf.c \
w_gamma.c \
w_gammaf.c \
w_gammaf_r.c \
w_gamma_r.c \
w_hypot.c \
w_hypotf.c \
w_j0.c \
w_j0f.c \
w_j1.c \
w_j1f.c \
w_jn.c \
w_jnf.c \
w_lgamma.c \
w_lgammaf.c \
w_lgammaf_r.c \
w_lgamma_r.c \
w_log10.c \
w_log10f.c \
w_log2.c \
w_log2f.c \
w_log.c \
w_logf.c \
w_pow.c \
w_powf.c \
w_remainder.c \
w_remainderf.c \
w_scalb.c \
w_scalbf.c \
w_sinh.c \
w_sinhf.c \
w_sqrt.c \
w_sqrtf.c \
COMPLEX_SRCS+=\
cabs.c \
cabsf.c \
cacos.c \
cacosf.c \
cacosh.c \
cacoshf.c \
carg.c \
cargf.c \
casin.c \
casinf.c \
casinh.c \
casinhf.c \
catan.c \
catanf.c \
catanh.c \
catanhf.c \
ccos.c \
ccosf.c \
ccosh.c \
ccoshf.c \
cephes_subr.c \
cephes_subrf.c \
cexp.c \
cexpf.c \
cimag.c \
cimagf.c \
cimagl.c \
clog.c \
clogf.c \
conj.c \
conjf.c \
conjl.c \
cpow.c \
cpowf.c \
cproj.c \
cprojf.c \
cprojl.c \
creal.c \
crealf.c \
creall.c \
csin.c \
csinf.c \
csinh.c \
csinhf.c \
csqrt.c \
csqrtf.c \
ctan.c \
ctanf.c \
ctanh.c \
ctanhf.c \
CFLAGS:=$(CFLAGS) -std=gnu99 -Wall -Wextra
CPPFLAGS:=$(CPPFLAGS) -I include -I src -I $(ARCH_SUBDIR)
# TODO: Figure out whether these are the defines that we want to pass.
CPPFLAGS:=$(CPPFLAGS) -D_MULTI_LIBM -D_POSIX_MODE
ARCH_SRCS:=$(addprefix $(ARCH_SUBDIR)/,$(ARCH_SRCS))
COMMON_SRCS:=$(addprefix src/,$(COMMON_SRCS))
COMPLEX_SRCS:=$(addprefix complex/,$(COMPLEX_SRCS))
SRCS:=$(ARCH_SRCS) $(COMMON_SRCS) $(COMPLEX_SRCS)
OBJS:=$(SRCS)
OBJS:=$(OBJS:.c=.o)
OBJS:=$(OBJS:.S=.o)
BINS:=libm.a
all: libs
libs: $(BINS)
.PHONY: libs headers clean install install-include-dirs install-headers \
install-libm-dirs install-libm install-libs
# TODO: Do not pick up the i387 asm version, it is incorrect
arch/i387/s_modf.o: src/s_modf.c
#.if (${MACHINE_ARCH} == "i386")
## XXX this gets miscompiled. There should be a better fix.
#COPTS.s_tanh.c+= -O0
#.endif
headers:
libm.a: $(OBJS)
$(HOSTAR) rcs $@ $(OBJS)
%.o: %.S
$(HOSTCC) -c $< -o $@ $(CPPFLAGS) $(CFLAGS)
%.o: %.c
$(HOSTCC) -c $< -o $@ $(CPPFLAGS) $(CFLAGS)
clean:
rm -f $(BINS) $(OBJS) $(ARCH_SUBDIR)/*.o src/*.o */*.o arch/*/*.o
# Installation into sysroot
install: install-headers install-libm
install-include-dirs: headers
mkdir -p $(DESTDIR)$(INCLUDEDIR)
mkdir -p $(DESTDIR)$(INCLUDEDIR)/$(HOST)
mkdir -p $(DESTDIR)$(INCLUDEDIR)/$(HOST)/machine
install-headers: install-include-dirs headers
cp -RTv include $(DESTDIR)$(INCLUDEDIR)
cp -v $(ARCH_MACHINE_HEADERS) $(DESTDIR)$(INCLUDEDIR)/$(HOST)/machine
install-libs: install-libm
install-libm-dirs:
mkdir -p $(DESTDIR)$(LIBDIR)
install-libm: install-libm-dirs libm.a
cp -P libm.a $(DESTDIR)$(LIBDIR)

68
libm/README Normal file
View File

@ -0,0 +1,68 @@
Sortix Math Library
===================
This is the Sortix Math Library (libm). It is a full implemention of the
<complex.h>, <fenv.h>, <math.h>, and <tgmath.h> API as described in the C
standard. A modern compiler should be able to build the library without any
warnings as the code has been modernized. Some platforms have optimized versions
of some functions available, but all functions are available as C code assuming
IEEE floating point semantics.
The library is a fork of the NetBSD 9.1 Math Library, with a few missing pieces
taken from the NetBSD 9.1 libc and kernel. The code has been modified to be part
of the Sortix operating system. However, we have tried to make as few changes to
the source code files themselves, so it should be easy to upgrade this library
if the upstream versions are upgraded as well. The internal header structure
tries to be BSD-like so the code can include BSD headers provided internally.
Some GNU extensions are implemented as well.
License
-------
The library is partly public domain and partly BSD-style licensed, see the file
LEGAL for information about which licenses are used. The files in this library
carry their original copyright headers, although a few lack such headers and are
assumed to carry the standard NetBSD license.
Currently the e_exp.S file contains an advertisement clause from Winning
Strategies, Inc., but otherwise the library is free of such requirements.
Porting
-------
The source code is reasonable portable and compiles cleanly with gcc as C99,
however the headers needs to be hooked up against the C library. As an example,
they currently support Sortix libc and GNU libc. You will also want to redo the
build system and probably fork the library. If you are the type that considers
porting a libm, then you probably should be able to do it without too much pain.
Standards Compliance
--------------------
There are two options in making libm at compile time:
_IEEE_LIBM --- IEEE libm; smaller, and somewhat faster
_MULTI_LIBM --- Support multi-standard at runtime by
imposing wrapper functions defined in
fdlibm.h:
_IEEE_MODE -- IEEE
_XOPEN_MODE -- X/OPEN
_POSIX_MODE -- POSIX/ANSI
_SVID3_MODE -- SVID
Here is how to set up CPPFLAGS to create the desired libm at
compile time:
CPPFLAGS = -D_IEEE_LIBM ... IEEE libm (recommended)
CPPFLAGS = -D_SVID3_MODE ... Multi-standard supported
libm with SVID as the
default standard
CPPFLAGS = -D_XOPEN_MODE ... Multi-standard supported
libm with XOPEN as the
default standard
CPPFLAGS = -D_POSIX_MODE ... Multi-standard supported
libm with POSIX as the
default standard
CPPFLAGS = ... Multi-standard supported
libm with IEEE as the
default standard

81
libm/arch/i387/abi.h Normal file
View File

@ -0,0 +1,81 @@
/* $NetBSD: abi.h,v 1.7 2011/06/18 22:19:52 joerg Exp $ */
/*
* Written by Frank van der Linden (fvdl@wasabisystems.com)
*/
/*
* The x86-64 ABI specifies that float and double arguments
* are passed in SSE2 (xmm) registers. Unfortunately,
* there is no way to push those on to the FP stack, which is
* where the fancier instructions get their arguments from.
*
* Define some prologues and epilogues to store and retrieve
* xmm regs to local variables.
*/
#ifdef __x86_64__
#define ARG_LONG_DOUBLE_ONE 8(%rsp)
#define ARG_LONG_DOUBLE_TWO 24(%rsp)
#define ARG_DOUBLE_ONE -8(%rsp)
#define ARG_DOUBLE_ONE_LSW -8(%rsp)
#define ARG_DOUBLE_ONE_MSW -4(%rsp)
#define ARG_DOUBLE_TWO -16(%rsp)
#define ARG_FLOAT_ONE -4(%rsp)
#define ARG_FLOAT_TWO -8(%rsp)
#define XMM_ONE_ARG_DOUBLE_PROLOGUE \
movsd %xmm0, ARG_DOUBLE_ONE
#define XMM_TWO_ARG_DOUBLE_PROLOGUE \
movsd %xmm0, ARG_DOUBLE_ONE ; \
movsd %xmm1, ARG_DOUBLE_TWO
#define XMM_ONE_ARG_FLOAT_PROLOGUE \
movss %xmm0, ARG_FLOAT_ONE
#define XMM_TWO_ARG_FLOAT_PROLOGUE \
movss %xmm0, ARG_FLOAT_ONE ; \
movss %xmm1, ARG_FLOAT_TWO
#define XMM_DOUBLE_EPILOGUE \
fstpl ARG_DOUBLE_ONE ; \
movsd ARG_DOUBLE_ONE, %xmm0
#define XMM_FLOAT_EPILOGUE \
fstps ARG_FLOAT_ONE ; \
movss ARG_FLOAT_ONE, %xmm0
#define FLDL_VAR(x) fldl x(%rip)
#else
#define ARG_LONG_DOUBLE_ONE 4(%esp)
#define ARG_LONG_DOUBLE_TWO 16(%esp)
#define ARG_DOUBLE_ONE 4(%esp)
#define ARG_DOUBLE_ONE_LSW 4(%esp)
#define ARG_DOUBLE_ONE_MSW 8(%esp)
#define ARG_DOUBLE_TWO 12(%esp)
#define ARG_FLOAT_ONE 4(%esp)
#define ARG_FLOAT_TWO 8(%esp)
#define XMM_ONE_ARG_DOUBLE_PROLOGUE
#define XMM_TWO_ARG_DOUBLE_PROLOGUE
#define XMM_ONE_ARG_FLOAT_PROLOGUE
#define XMM_TWO_ARG_FLOAT_PROLOGUE
#define XMM_DOUBLE_EPILOGUE
#define XMM_FLOAT_EPILOGUE
#ifdef PIC
#define FLDL_VAR(x) \
PIC_PROLOGUE ; \
fldl PIC_GOTOFF(x) ; \
PIC_EPILOGUE
#else
#define FLDL_VAR(x) \
fldl x
#endif
#endif

24
libm/arch/i387/e_acos.S Normal file
View File

@ -0,0 +1,24 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_acos.S,v 1.8 2003/07/26 19:24:57 salo Exp $")
/* acos = atan (sqrt(1 - x^2) / x) */
ENTRY(__ieee754_acos)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE /* x */
fld %st(0)
fmul %st(0) /* x^2 */
fld1
fsubp /* 1 - x^2 */
fsqrt /* sqrt (1 - x^2) */
fxch %st(1)
fpatan
XMM_DOUBLE_EPILOGUE
ret

23
libm/arch/i387/e_asin.S Normal file
View File

@ -0,0 +1,23 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_asin.S,v 1.7 2003/07/26 19:24:58 salo Exp $")
/* asin = atan (x / sqrt(1 - x^2)) */
ENTRY(__ieee754_asin)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE /* x */
fld %st(0)
fmul %st(0) /* x^2 */
fld1
fsubp /* 1 - x^2 */
fsqrt /* sqrt (1 - x^2) */
fpatan
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/e_atan2.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_atan2.S,v 1.6 2003/07/26 19:24:58 salo Exp $")
ENTRY(__ieee754_atan2)
XMM_TWO_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE
fldl ARG_DOUBLE_TWO
fpatan
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/e_atan2f.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_atan2f.S,v 1.3 2003/07/26 19:24:58 salo Exp $")
ENTRY(__ieee754_atan2f)
XMM_TWO_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_ONE
flds ARG_FLOAT_TWO
fpatan
XMM_FLOAT_EPILOGUE
ret

108
libm/arch/i387/e_exp.S Normal file
View File

@ -0,0 +1,108 @@
/* $NetBSD: e_exp.S,v 1.14 2008/06/23 10:24:13 drochner Exp $ */
/*
* Copyright (c) 1993,94 Winning Strategies, Inc.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Winning Strategies, Inc.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
*/
/*
* Written by:
* J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_exp.S,v 1.14 2008/06/23 10:24:13 drochner Exp $")
#if 0
RCSID("$FreeBSD: src/lib/msun/i387/e_exp.S,v 1.8.2.1 2000/07/10 09:16:28 obrien Exp $")
#endif
/* e^x = 2^(x * log2(e)) */
ENTRY(__ieee754_exp)
XMM_ONE_ARG_DOUBLE_PROLOGUE
/*
* If x is +-Inf, then the subtraction would give Inf-Inf = NaN.
* Avoid this. Also avoid it if x is NaN for convenience.
*/
movl ARG_DOUBLE_ONE_MSW, %eax
andl $0x7fffffff, %eax
cmpl $0x7ff00000, %eax
jae x_Inf_or_NaN
fldl ARG_DOUBLE_ONE
/*
* Ensure that the rounding mode is to nearest (to give the smallest
* possible fraction) and that the precision is as high as possible.
* We may as well mask interrupts if we switch the mode.
*/
#define CWSTORE_SAV ARG_DOUBLE_ONE_LSW /* XXX overwrites the argument */
#define CWSTORE_TMP ARG_DOUBLE_ONE_MSW
fstcw CWSTORE_SAV
movl CWSTORE_SAV, %eax
andl $0x0f00, %eax
cmpl $0x0300, %eax /* RC == 0 && PC == 3? */
je 1f /* jump if mode is good */
movl $0x137f, CWSTORE_TMP
fldcw CWSTORE_TMP
1:
fldl2e
fmulp /* x * log2(e) */
fst %st(1)
frndint /* int(x * log2(e)) */
fst %st(2)
fsubrp /* fract(x * log2(e)) */
f2xm1 /* 2^(fract(x * log2(e))) - 1 */
fld1
faddp /* 2^(fract(x * log2(e))) */
fscale /* e^x */
fstp %st(1)
je 1f
fldcw CWSTORE_SAV
1:
XMM_DOUBLE_EPILOGUE
ret
x_Inf_or_NaN:
/*
* Return 0 if x is -Inf. Otherwise just return x, although the
* C version would return (x + x) (Real Indefinite) if x is a NaN.
*/
cmpl $0xfff00000, ARG_DOUBLE_ONE_MSW
jne x_not_minus_Inf
cmpl $0, ARG_DOUBLE_ONE_LSW
jne x_not_minus_Inf
fldz
XMM_DOUBLE_EPILOGUE
ret
x_not_minus_Inf:
fldl ARG_DOUBLE_ONE
XMM_DOUBLE_EPILOGUE
ret

55
libm/arch/i387/e_expf.S Normal file
View File

@ -0,0 +1,55 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_expf.S,v 1.6 2008/06/24 17:27:56 drochner Exp $")
/* e^x = 2^(x * log2(e)) */
ENTRY(__ieee754_expf)
XMM_ONE_ARG_FLOAT_PROLOGUE
/*
* catch +/-Inf and NaN arguments
*/
movl ARG_FLOAT_ONE,%eax
andl $0x7fffffff,%eax
cmpl $0x7f800000,%eax
jae x_Inf_or_NaN
flds ARG_FLOAT_ONE
fldl2e
fmulp /* x * log2(e) */
fld %st(0)
frndint /* int(x * log2(e)) */
fsubr %st(0),%st(1) /* fract(x * log2(e)) */
fxch
f2xm1 /* 2^(fract(x * log2(e))) - 1 */
fld1
faddp /* 2^(fract(x * log2(e))) */
fscale /* e^x */
fstp %st(1)
XMM_FLOAT_EPILOGUE
ret
x_Inf_or_NaN:
/*
* Return 0 if x is -Inf. Otherwise just return x, although the
* C version would return (x + x) (Real Indefinite) if x is a NaN.
*/
movl ARG_FLOAT_ONE,%eax
cmpl $0xff800000,%eax
jne x_not_minus_Inf
fldz
XMM_FLOAT_EPILOGUE
ret
x_not_minus_Inf:
flds ARG_FLOAT_ONE
XMM_FLOAT_EPILOGUE
ret

23
libm/arch/i387/e_fmod.S Normal file
View File

@ -0,0 +1,23 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_fmod.S,v 1.7 2003/07/26 19:24:58 salo Exp $")
ENTRY(__ieee754_fmod)
XMM_TWO_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_TWO
fldl ARG_DOUBLE_ONE
1: fprem
fstsw %ax
btw $10,%ax
jc 1b
fstp %st(1)
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/e_log.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_log.S,v 1.6 2003/07/26 19:24:58 salo Exp $")
ENTRY(__ieee754_log)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldln2
fldl ARG_DOUBLE_ONE
fyl2x
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/e_log10.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_log10.S,v 1.6 2003/07/26 19:24:59 salo Exp $")
ENTRY(__ieee754_log10)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldlg2
fldl ARG_DOUBLE_ONE
fyl2x
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/e_log10f.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_log10f.S,v 1.3 2003/07/26 19:24:59 salo Exp $")
ENTRY(__ieee754_log10f)
XMM_ONE_ARG_FLOAT_PROLOGUE
fldlg2
flds ARG_FLOAT_ONE
fyl2x
XMM_FLOAT_EPILOGUE
ret

18
libm/arch/i387/e_log2.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by Rui Paulo <rpaulo@NetBSD.org>, based on e_log.S.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_log2.S,v 1.1 2005/07/21 20:58:21 rpaulo Exp $")
ENTRY(__ieee754_log2)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fld1
fldl ARG_DOUBLE_ONE
fyl2x
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/e_log2f.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by Rui Paulo <rpaulo@NetBSD.org>, based on e_logf.S.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_log2f.S,v 1.1 2005/07/21 20:58:21 rpaulo Exp $")
ENTRY(__ieee754_log2f)
XMM_ONE_ARG_FLOAT_PROLOGUE
fld1
flds ARG_FLOAT_ONE
fyl2x
XMM_FLOAT_EPILOGUE
ret

18
libm/arch/i387/e_logf.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_logf.S,v 1.4 2003/07/26 19:24:59 salo Exp $")
ENTRY(__ieee754_logf)
XMM_ONE_ARG_FLOAT_PROLOGUE
fldln2
flds ARG_FLOAT_ONE
fyl2x
XMM_FLOAT_EPILOGUE
ret

View File

@ -0,0 +1,22 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_remainder.S,v 1.7 2003/07/26 19:24:59 salo Exp $")
ENTRY(__ieee754_remainder)
XMM_TWO_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_TWO
fldl ARG_DOUBLE_ONE
1: fprem1
fstsw %ax
btw $10,%ax
jc 1b
fstp %st(1)
XMM_DOUBLE_EPILOGUE
ret

View File

@ -0,0 +1,22 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_remainderf.S,v 1.5 2003/07/26 19:24:59 salo Exp $")
ENTRY(__ieee754_remainderf)
XMM_TWO_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_TWO
flds ARG_FLOAT_ONE
1: fprem1
fstsw %ax
btw $10,%ax
jc 1b
fstp %st(1)
XMM_FLOAT_EPILOGUE
ret

19
libm/arch/i387/e_scalb.S Normal file
View File

@ -0,0 +1,19 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_scalb.S,v 1.7 2003/07/26 19:25:00 salo Exp $")
ENTRY(__ieee754_scalb)
XMM_TWO_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_TWO
fldl ARG_DOUBLE_ONE
fscale
fstp %st(1) /* bug fix for fp stack overflow */
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/e_scalbf.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: e_scalbf.S,v 1.3 2003/07/26 19:25:00 salo Exp $")
ENTRY(__ieee754_scalbf)
XMM_TWO_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_TWO
flds ARG_FLOAT_ONE
fscale
XMM_FLOAT_EPILOGUE
ret

17
libm/arch/i387/e_sqrt.S Normal file
View File

@ -0,0 +1,17 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: e_sqrt.S,v 1.6 2003/07/26 19:25:00 salo Exp $")
ENTRY(__ieee754_sqrt)
#ifdef __i386__
fldl 4(%esp)
fsqrt
#else
sqrtsd %xmm0,%xmm0
#endif
ret

17
libm/arch/i387/e_sqrtf.S Normal file
View File

@ -0,0 +1,17 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: e_sqrtf.S,v 1.4 2003/07/26 19:25:00 salo Exp $")
ENTRY(__ieee754_sqrtf)
#ifdef __i386__
flds 4(%esp)
fsqrt
#else
sqrtss %xmm0,%xmm0
#endif
ret

45
libm/arch/i387/fabs.S Normal file
View File

@ -0,0 +1,45 @@
/* $NetBSD: fabs.S,v 1.5 2003/08/07 16:42:07 agc Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
* from: @(#)fabs.s 5.2 (Berkeley) 12/17/90
*/
#include <machine/asm.h>
#if defined(LIBC_SCCS)
RCSID("$NetBSD: fabs.S,v 1.5 2003/08/07 16:42:07 agc Exp $")
#endif
ENTRY(fabs)
fldl 4(%esp)
fabs
ret

522
libm/arch/i387/fenv.c Normal file
View File

@ -0,0 +1,522 @@
/* $NetBSD: fenv.c,v 1.3.8.1.6.1 2013/06/14 02:43:36 msaitoh Exp $ */
/*-
* 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: fenv.c,v 1.3.8.1.6.1 2013/06/14 02:43:36 msaitoh Exp $");
#include <assert.h>
#include <fenv.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
/* Load x87 Control Word */
#define __fldcw(__cw) __asm__ __volatile__ \
("fldcw %0" : : "m" (__cw))
/* No-Wait Store Control Word */
#define __fnstcw(__cw) __asm__ __volatile__ \
("fnstcw %0" : "=m" (*(__cw)))
/* No-Wait Store Status Word */
#define __fnstsw(__sw) __asm__ __volatile__ \
("fnstsw %0" : "=am" (*(__sw)))
/* No-Wait Clear Exception Flags */
#define __fnclex() __asm__ __volatile__ \
("fnclex")
/* Load x87 Environment */
#define __fldenv(__env) __asm__ __volatile__ \
("fldenv %0" : : "m" (__env))
/* No-Wait Store x87 environment */
#define __fnstenv(__env) __asm__ __volatile__ \
("fnstenv %0" : "=m" (*(__env)))
/* Check for and handle pending unmasked x87 pending FPU exceptions */
#define __fwait(__env) __asm__ __volatile__ \
("fwait")
/* Load the MXCSR register */
#define __ldmxcsr(__mxcsr) __asm__ __volatile__ \
("ldmxcsr %0" : : "m" (__mxcsr))
/* Store the MXCSR register state */
#define __stmxcsr(__mxcsr) __asm__ __volatile__ \
("stmxcsr %0" : "=m" (*(__mxcsr)))
/*
* The following constant represents the default floating-point environment
* (that is, the one installed at program startup) and has type pointer to
* const-qualified fenv_t.
*
* It can be used as an argument to the functions within the <fenv.h> header
* that manage the floating-point environment, namely fesetenv() and
* feupdateenv().
*
* x87 fpu registers are 16bit wide. The upper bits, 31-16, are marked as
* RESERVED. We provide a partial floating-point environment, where we
* define only the lower bits. The reserved bits are extracted and set by the
* consumers of FE_DFL_ENV, during runtime.
*/
fenv_t __fe_dfl_env = {
{
__NetBSD_NPXCW__, /* Control word register */
0x0, /* Unused */
0x0000, /* Status word register */
0x0, /* Unused */
0x0000ffff, /* Tag word register */
0x0, /* Unused */
{
0x0000, 0x0000,
0x0000, 0xffff
}
},
__INITIAL_MXCSR__ /* MXCSR register */
};
/*
* Test for SSE support on this processor.
*
* We need to use ldmxcsr/stmxcsr to get correct results if any part
* of the program was compiled to use SSE floating-point, but we can't
* use SSE on older processors.
*
* In order to do so, we need to query the processor capabilities via the CPUID
* instruction. We can make it even simpler though, by querying the machdep.sse
* sysctl.
*/
static int __HAS_SSE = 0;
static void __test_sse(void) __attribute__ ((constructor));
static void __test_sse(void)
{
#if 0
size_t oldlen = sizeof(__HAS_SSE);
int rv;
/* TODO: Properly detect whether see is available! */
rv = sysctlbyname("machdep.sse", &__HAS_SSE, &oldlen, NULL, 0);
if (rv == -1)
__HAS_SSE = 0;
#elif defined(__SSE__)
__HAS_SSE = 1;
#elif defined(__sortix__)
__HAS_SSE = 1; /* Currently unconditionally enabled and needed to boot. */
#else
__HAS_SSE = 0;
#endif
}
/*
* The feclearexcept() function clears the supported floating-point exceptions
* represented by `excepts'.
*/
int
feclearexcept(int excepts)
{
fenv_t env;
uint32_t mxcsr;
int ex;
assert((excepts & ~FE_ALL_EXCEPT) == 0);
ex = excepts & FE_ALL_EXCEPT;
/* It's ~3x faster to call fnclex, than store/load fp env */
if (ex == FE_ALL_EXCEPT) {
__fnclex();
} else {
__fnstenv(&env);
env.x87.status &= ~ex;
__fldenv(env);
}
if (__HAS_SSE) {
__stmxcsr(&mxcsr);
mxcsr &= ~ex;
__ldmxcsr(mxcsr);
}
/* Success */
return (0);
}
/*
* The fegetexceptflag() function stores an implementation-defined
* representation of the states of the floating-point status flags indicated by
* the argument excepts in the object pointed to by the argument flagp.
*/
int
fegetexceptflag(fexcept_t *flagp, int excepts)
{
uint32_t mxcsr;
uint16_t status;
int ex;
assert(flagp != NULL);
assert((excepts & ~FE_ALL_EXCEPT) == 0);
ex = excepts & FE_ALL_EXCEPT;
__fnstsw(&status);
if (__HAS_SSE)
__stmxcsr(&mxcsr);
else
mxcsr = 0;
*flagp = (mxcsr | status) & ex;
/* Success */
return (0);
}
/*
* The feraiseexcept() function raises the supported floating-point exceptions
* represented by the argument `excepts'.
*
* The standard explicitly allows us to execute an instruction that has the
* exception as a side effect, but we choose to manipulate the status register
* directly.
*
* The validation of input is being deferred to fesetexceptflag().
*/
int
feraiseexcept(int excepts)
{
fexcept_t ex;
assert((excepts & ~FE_ALL_EXCEPT) == 0);
ex = excepts & FE_ALL_EXCEPT;
fesetexceptflag(&ex, excepts);
__fwait();
/* Success */
return (0);
}
/*
* This function sets the floating-point status flags indicated by the argument
* `excepts' to the states stored in the object pointed to by `flagp'. It does
* NOT raise any floating-point exceptions, but only sets the state of the flags.
*/
int
fesetexceptflag(const fexcept_t *flagp, int excepts)
{
fenv_t env;
uint32_t mxcsr;
int ex;
assert(flagp != NULL);
assert((excepts & ~FE_ALL_EXCEPT) == 0);
ex = excepts & FE_ALL_EXCEPT;
__fnstenv(&env);
env.x87.status &= ~ex;
env.x87.status |= *flagp & ex;
__fldenv(env);
if (__HAS_SSE) {
__stmxcsr(&mxcsr);
mxcsr &= ~ex;
mxcsr |= *flagp & ex;
__ldmxcsr(mxcsr);
}
/* Success */
return (0);
}
/*
* The fetestexcept() function determines which of a specified subset of the
* floating-point exception flags are currently set. The `excepts' argument
* specifies the floating-point status flags to be queried.
*/
int
fetestexcept(int excepts)
{
uint32_t mxcsr;
uint16_t status;
int ex;
assert((excepts & ~FE_ALL_EXCEPT) == 0);
ex = excepts & FE_ALL_EXCEPT;
__fnstsw(&status);
if (__HAS_SSE)
__stmxcsr(&mxcsr);
else
mxcsr = 0;
return ((status | mxcsr) & ex);
}
int
fegetround(void)
{
uint16_t control;
/*
* We assume that the x87 and the SSE unit agree on the
* rounding mode. Reading the control word on the x87 turns
* out to be about 5 times faster than reading it on the SSE
* unit on an Opteron 244.
*/
__fnstcw(&control);
return (control & __X87_ROUND_MASK);
}
/*
* The fesetround() function shall establish the rounding direction represented
* by its argument round. If the argument is not equal to the value of a
* rounding direction macro, the rounding direction is not changed.
*/
int
fesetround(int round)
{
uint32_t mxcsr;
uint16_t control;
if (round & ~__X87_ROUND_MASK) {
/* Failure */
return (-1);
}
__fnstcw(&control);
control &= ~__X87_ROUND_MASK;
control |= round;
__fldcw(control);
if (__HAS_SSE) {
__stmxcsr(&mxcsr);
mxcsr &= ~(__X87_ROUND_MASK << __SSE_ROUND_SHIFT);
mxcsr |= round << __SSE_ROUND_SHIFT;
__ldmxcsr(mxcsr);
}
/* Success */
return (0);
}
/*
* The fegetenv() function attempts to store the current floating-point
* environment in the object pointed to by envp.
*/
int
fegetenv(fenv_t *envp)
{
uint32_t mxcsr;
assert(envp != NULL);
/*
* fnstenv masks all exceptions, so we need to restore the old control
* word to avoid this side effect.
*/
__fnstenv(envp);
__fldcw(envp->x87.control);
if (__HAS_SSE) {
__stmxcsr(&mxcsr);
envp->mxcsr = mxcsr;
}
/* Success */
return (0);
}
/*
* The feholdexcept() function saves the current floating-point environment in
* the object pointed to by envp, clears the floating-point status flags, and
* then installs a non-stop (continue on floating-point exceptions) mode, if
* available, for all floating-point exceptions.
*/
int
feholdexcept(fenv_t *envp)
{
uint32_t mxcsr;
assert(envp != NULL);
__fnstenv(envp);
__fnclex();
if (__HAS_SSE) {
__stmxcsr(&mxcsr);
envp->mxcsr = mxcsr;
mxcsr &= ~FE_ALL_EXCEPT;
mxcsr |= FE_ALL_EXCEPT << __SSE_EMASK_SHIFT;
__ldmxcsr(mxcsr);
}
/* Success */
return (0);
}
/*
* The fesetenv() function attempts to establish the floating-point environment
* represented by the object pointed to by envp. The argument `envp' points
* to an object set by a call to fegetenv() or feholdexcept(), or equal a
* floating-point environment macro. The fesetenv() function does not raise
* floating-point exceptions, but only installs the state of the floating-point
* status flags represented through its argument.
*/
int
fesetenv(const fenv_t *envp)
{
fenv_t env;
assert(envp != NULL);
/* Store the x87 floating-point environment */
memset(&env, 0, sizeof(env));
__fnstenv(&env);
__fe_dfl_env.x87.unused1 = env.x87.unused1;
__fe_dfl_env.x87.unused2 = env.x87.unused2;
__fe_dfl_env.x87.unused3 = env.x87.unused3;
memcpy(__fe_dfl_env.x87.others,
env.x87.others,
sizeof(__fe_dfl_env.x87.others) / sizeof(uint32_t));
__fldenv(envp->x87);
if (__HAS_SSE)
__ldmxcsr(envp->mxcsr);
/* Success */
return (0);
}
/*
* The feupdateenv() function saves the currently raised floating-point
* exceptions in its automatic storage, installs the floating-point environment
* represented by the object pointed to by `envp', and then raises the saved
* floating-point exceptions. The argument `envp' shall point to an object set
* by a call to feholdexcept() or fegetenv(), or equal a floating-point
* environment macro.
*/
int
feupdateenv(const fenv_t *envp)
{
fenv_t env;
uint32_t mxcsr;
uint16_t status;
assert(envp != NULL);
/* Store the x87 floating-point environment */
memset(&env, 0, sizeof(env));
__fnstenv(&env);
__fe_dfl_env.x87.unused1 = env.x87.unused1;
__fe_dfl_env.x87.unused2 = env.x87.unused2;
__fe_dfl_env.x87.unused3 = env.x87.unused3;
memcpy(__fe_dfl_env.x87.others,
env.x87.others,
sizeof(__fe_dfl_env.x87.others) / sizeof(uint32_t));
__fnstsw(&status);
if (__HAS_SSE)
__stmxcsr(&mxcsr);
else
mxcsr = 0;
fesetenv(envp);
feraiseexcept((mxcsr | status) & FE_ALL_EXCEPT);
/* Success */
return (0);
}
/*
* The following functions are extentions to the standard
*/
int
feenableexcept(int mask)
{
uint32_t mxcsr, omask;
uint16_t control;
mask &= FE_ALL_EXCEPT;
__fnstcw(&control);
if (__HAS_SSE)
__stmxcsr(&mxcsr);
else
mxcsr = 0;
omask = (control | mxcsr >> __SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
control &= ~mask;
__fldcw(control);
if (__HAS_SSE) {
mxcsr &= ~(mask << __SSE_EMASK_SHIFT);
__ldmxcsr(mxcsr);
}
return (FE_ALL_EXCEPT & ~omask);
}
int
fedisableexcept(int mask)
{
uint32_t mxcsr, omask;
uint16_t control;
mask &= FE_ALL_EXCEPT;
__fnstcw(&control);
if (__HAS_SSE)
__stmxcsr(&mxcsr);
else
mxcsr = 0;
omask = (control | mxcsr >> __SSE_EMASK_SHIFT) & FE_ALL_EXCEPT;
control |= mask;
__fldcw(control);
if (__HAS_SSE) {
mxcsr |= mask << __SSE_EMASK_SHIFT;
__ldmxcsr(mxcsr);
}
return (FE_ALL_EXCEPT & ~omask);
}
int
fegetexcept(void)
{
uint16_t control;
/*
* We assume that the masks for the x87 and the SSE unit are
* the same.
*/
__fnstcw(&control);
return (~control & FE_ALL_EXCEPT);
}

View File

@ -0,0 +1,21 @@
/* $NetBSD: flt_rounds.S,v 1.9 2011/09/30 23:42:00 christos Exp $ */
#include <machine/asm.h>
/*
* 00 0 round to zero
* 01 1 round to nearest
* 10 2 round to positive infinity
* 11 3 round to negative infinity
*/
.text
_ALIGN_TEXT
ENTRY(__flt_rounds)
fnstcw -4(%esp)
movl -4(%esp), %ecx
shrl $9, %ecx
andl $6, %ecx
movl $0x2d, %eax /* 0x2d = 00.10.11.01 */
sarl %cl, %eax /* 0,1,2,3 -> 1,3,2,0 */
andl $3, %eax
ret

View File

@ -0,0 +1,22 @@
/* $NetBSD: fpgetmask.S,v 1.4 2002/01/13 21:45:42 thorpej Exp $ */
/*
* Written by J.T. Conklin, Apr 4, 1995
* Public domain.
*/
#include <machine/asm.h>
#ifdef WEAK_ALIAS
WEAK_ALIAS(fpgetmask, _fpgetmask)
ENTRY(_fpgetmask)
#else
ENTRY(fpgetmask)
#endif
subl $4,%esp
fnstcw (%esp)
movl (%esp),%eax
notl %eax
andl $63,%eax
addl $4,%esp
ret

View File

@ -0,0 +1,22 @@
/* $NetBSD: fpgetprec.S,v 1.1 2011/03/26 19:51:41 christos Exp $ */
/*
* Written by J.T. Conklin, Apr 4, 1995
* Public domain.
*/
#include <machine/asm.h>
#ifdef WEAK_ALIAS
WEAK_ALIAS(fpgetprec, _fpgetprec)
ENTRY(_fpgetprec)
#else
ENTRY(fpgetprec)
#endif
subl $4,%esp
fnstcw (%esp)
movl (%esp),%eax
rorl $8,%eax
andl $3,%eax
addl $4,%esp
ret

View File

@ -0,0 +1,23 @@
/* $NetBSD: fpgetround.S,v 1.6 2011/09/30 23:42:00 christos Exp $ */
/*
* Written by J.T. Conklin, Apr 4, 1995
* Public domain.
*/
#include <machine/asm.h>
/*
* XXX load only x87 state.
*/
#ifdef WEAK_ALIAS
WEAK_ALIAS(fpgetround, _fpgetround)
ENTRY(_fpgetround)
#else
ENTRY(fpgetround)
#endif
fnstcw -4(%esp)
movl -4(%esp), %eax
andl $0x00000c00, %eax
ret

View File

@ -0,0 +1,21 @@
/* $NetBSD: fpgetsticky.S,v 1.6 2002/01/13 21:45:43 thorpej Exp $ */
/*
* Written by J.T. Conklin, Apr 4, 1995
* Public domain.
*/
#include <machine/asm.h>
#ifdef WEAK_ALIAS
WEAK_ALIAS(fpgetsticky, _fpgetsticky)
ENTRY(_fpgetsticky)
#else
ENTRY(fpgetsticky)
#endif
subl $4,%esp
fnstsw (%esp)
movl (%esp),%eax
andl $63,%eax
addl $4,%esp
ret

View File

@ -0,0 +1,33 @@
/* $NetBSD: fpsetmask.S,v 1.4 2002/01/13 21:45:43 thorpej Exp $ */
/*
* Written by Charles M. Hannum, Apr 9, 1995
* Public domain.
*/
#include <machine/asm.h>
#ifdef WEAK_ALIAS
WEAK_ALIAS(fpsetmask, _fpsetmask)
ENTRY(_fpsetmask)
#else
ENTRY(fpsetmask)
#endif
subl $4,%esp
fnstcw (%esp)
movl (%esp),%eax
movl %eax,%edx
notl %eax
andl $63,%eax
addl %eax,%edx
movl 8(%esp),%ecx
andl $63,%ecx
subl %ecx,%edx
movl %edx,(%esp)
fldcw (%esp)
addl $4,%esp
ret

View File

@ -0,0 +1,34 @@
/* $NetBSD: fpsetprec.S,v 1.1 2011/03/26 19:51:41 christos Exp $ */
/*
* Written by Charles M. Hannum, Apr 9, 1995
* Public domain.
*/
#include <machine/asm.h>
#ifdef WEAK_ALIAS
WEAK_ALIAS(fpsetprec, _fpsetprec)
ENTRY(_fpsetprec)
#else
ENTRY(fpsetprec)
#endif
subl $4,%esp
fnstcw (%esp)
movl (%esp),%eax
rorl $8,%eax
movl %eax,%edx
andl $3,%eax
subl %eax,%edx
movl 8(%esp),%ecx
andl $3,%ecx
orl %ecx,%edx
roll $8,%edx
movl %edx,(%esp)
fldcw (%esp)
addl $4,%esp
ret

View File

@ -0,0 +1,33 @@
/* $NetBSD: fpsetround.S,v 1.5 2011/09/30 23:45:41 christos Exp $ */
/*
* Written by Frank van der Linden at Wasabi Systems for NetBSD.
* Public domain.
*/
#include <machine/asm.h>
/*
* XXX set both the x87 control word
* Applications should only set exception and round flags
*/
#ifdef WEAK_ALIAS
WEAK_ALIAS(fpsetround, _fpsetround)
ENTRY(_fpsetround)
#else
ENTRY(fpsetround)
#endif
fnstcw -4(%esp)
movl -4(%esp), %edx
movl %edx, %eax
andl $0x00000c00, %eax
andl $0xfffff3ff, %edx
movl 4(%esp), %ecx
orl %ecx, %edx
movl %edx, -4(%esp)
fldcw -4(%esp)
ret

View File

@ -0,0 +1,32 @@
/* $NetBSD: fpsetsticky.S,v 1.6 2002/01/13 21:45:43 thorpej Exp $ */
/*
* Written by Charles M. Hannum, Apr 9, 1995
* Public domain.
*/
#include <machine/asm.h>
#ifdef WEAK_ALIAS
WEAK_ALIAS(fpsetsticky, _fpsetsticky)
ENTRY(_fpsetsticky)
#else
ENTRY(fpsetsticky)
#endif
subl $28,%esp
fnstenv (%esp)
movl 4(%esp),%eax
movl %eax,%edx
andl $63,%eax
subl %eax,%edx
movl 32(%esp),%ecx
andl $63,%ecx
addl %ecx,%edx
movl %edx,4(%esp)
fldenv (%esp)
addl $28,%esp
ret

23
libm/arch/i387/lrint.S Normal file
View File

@ -0,0 +1,23 @@
/* $NetBSD: lrint.S,v 1.2 2004/10/13 15:18:32 drochner Exp $ */
/*
* Written by Matthias Drochner <drochner@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
ENTRY(lrint)
#ifdef __i386__
pushl %ebp
movl %esp,%ebp
subl $4,%esp
fldl 8(%ebp)
fistpl (%esp)
movl (%esp),%eax
leave
ret
#else
cvtsd2siq %xmm0,%rax
ret
#endif

View File

@ -0,0 +1,124 @@
/* $NetBSD: asm.h,v 1.40 2011/06/16 13:16:20 joerg Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
* @(#)asm.h 5.5 (Berkeley) 5/7/91
*/
/* This is a cut down version of netbsd <machine/asm.h>. */
#ifndef INCLUDE_MACHINE_ASM_H
#define INCLUDE_MACHINE_ASM_H
#ifdef PIC
#define PIC_PROLOGUE \
pushl %ebx; \
call 1f; \
1: \
popl %ebx; \
addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
#define PIC_EPILOGUE \
popl %ebx
#define PIC_PLT(x) x@PLT
#define PIC_GOT(x) x@GOT(%ebx)
#define PIC_GOTOFF(x) x@GOTOFF(%ebx)
#else
#define PIC_PROLOGUE
#define PIC_EPILOGUE
#define PIC_PLT(x) x
#define PIC_GOT(x) x
#define PIC_GOTOFF(x) x
#endif
#define _C_LABEL(x) x
#define _ASM_LABEL(x) x
#define CVAROFF(x, y) _C_LABEL(x) + y
#define __CONCAT(x,y) x ## y
#define __STRING(x) #x
/* let kernels and others override entrypoint alignment */
#if !defined(_ALIGN_TEXT) && !defined(_KERNEL)
# ifdef _STANDALONE
# define _ALIGN_TEXT .align 1
# elif defined __ELF__
# define _ALIGN_TEXT .align 16
# else
# define _ALIGN_TEXT .align 4
# endif
#endif
#define _ENTRY(x) \
.text; _ALIGN_TEXT; .globl x; .type x,@function; x:
#define _LABEL(x) \
.globl x; x:
#ifdef GPROF
# define _PROF_PROLOGUE \
pushl %ebp; movl %esp,%ebp; call PIC_PLT(__mcount); popl %ebp
#else
# define _PROF_PROLOGUE
#endif
#define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
#define NENTRY(y) _ENTRY(_C_LABEL(y))
#define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
#define LABEL(y) _LABEL(_C_LABEL(y))
#define END(y) .size y, . - y
#define ASMSTR .asciz
#ifdef __ELF__
#define RCSID(x) .pushsection ".ident"; .asciz x; .popsection
#else
#define RCSID(x) .text; .asciz x
#endif
#define WEAK_ALIAS(alias,sym) \
.weak alias; \
alias = sym
/*
* STRONG_ALIAS: create a strong alias.
*/
#define STRONG_ALIAS(alias,sym) \
.globl alias; \
alias = sym
#define WARN_REFERENCES(sym,msg) \
.pushsection .gnu.warning. ## sym; \
.ascii msg; \
.popsection
#endif /* !INCLUDE_MACHINE_ASM_H */

View File

@ -0,0 +1,116 @@
/* $NetBSD: fenv.h,v 1.1 2010/07/31 21:47:54 joerg Exp $ */
/*-
* Copyright (c) 2004-2005 David Schultz <das (at) 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.
*/
#ifndef INCLUDE_MACHINE_FENV_H
#define INCLUDE_MACHINE_FENV_H
#include <__/stdint.h>
#include <machine/npx.h>
/*
* Each symbol representing a floating point exception expands to an integer
* constant expression with values, such that bitwise-inclusive ORs of _all
* combinations_ of the constants result in distinct values.
*
* We use such values that allow direct bitwise operations on FPU/SSE registers.
*/
#define FE_INVALID 0x01 /* 000000000001 */
#define FE_DENORMAL 0x02 /* 000000000010 */
#define FE_DIVBYZERO 0x04 /* 000000000100 */
#define FE_OVERFLOW 0x08 /* 000000001000 */
#define FE_UNDERFLOW 0x10 /* 000000010000 */
#define FE_INEXACT 0x20 /* 000000100000 */
/*
* The following symbol is simply the bitwise-inclusive OR of all floating-point
* exception constants defined above.
*/
#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
/*
* Each symbol representing the rounding direction, expands to an integer
* constant expression whose value is distinct non-negative value.
*
* We use such values that allow direct bitwise operations on FPU/SSE registers.
*/
#define FE_TONEAREST 0x000 /* 000000000000 */
#define FE_DOWNWARD 0x400 /* 010000000000 */
#define FE_UPWARD 0x800 /* 100000000000 */
#define FE_TOWARDZERO 0xC00 /* 110000000000 */
/*
* As compared to the x87 control word, the SSE unit's control has the rounding
* control bits offset by 3 and the exception mask bits offset by 7
*/
#define __X87_ROUND_MASK 0xC00 /* 110000000000 */
#define __SSE_ROUND_SHIFT 3
#define __SSE_EMASK_SHIFT 7
/*
* fenv_t represents the entire floating-point environment
*/
typedef struct {
struct {
__uint16_t control; /* Control word register */
__uint16_t unused1;
__uint16_t status; /* Status word register */
__uint16_t unused2;
__uint16_t tag; /* Tag word register */
__uint16_t unused3;
__uint32_t others[4]; /* EIP, Pointer Selector, etc */
} x87;
__uint32_t mxcsr; /* Control and status register */
} fenv_t;
/*
* The following constant represents the default floating-point environment
* (that is, the one installed at program startup) and has type pointer to
* const-qualified fenv_t.
*
* It can be used as an argument to the functions within the <fenv.h> header
* that manage the floating-point environment.
*/
extern fenv_t __fe_dfl_env;
#define FE_DFL_ENV ((const fenv_t *) &__fe_dfl_env)
/*
* fexcept_t represents the floating-point status flags collectively, including
* any status the implementation associates with the flags.
*
* A floating-point status flag is a system variable whose value is set (but
* never cleared) when a floating-point exception is raised, which occurs as a
* side effect of exceptional floating-point arithmetic to provide auxiliary
* information.
*
* A floating-point control mode is a system variable whose value may be set by
* the user to affect the subsequent behavior of floating-point arithmetic.
*/
typedef __uint32_t fexcept_t;
#endif /* !INCLUDE_MACHINE_FENV_H */

View File

@ -0,0 +1,197 @@
/* $NetBSD: npx.h,v 1.25 2010/07/31 21:47:54 joerg Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
* @(#)npx.h 5.3 (Berkeley) 1/18/91
*/
/*
* 287/387 NPX Coprocessor Data Structures and Constants
* W. Jolitz 1/90
*/
#ifndef _I386_NPX_H_
#define _I386_NPX_H_
/* Environment information of floating point unit */
struct env87 {
long en_cw; /* control word (16bits) */
long en_sw; /* status word (16bits) */
long en_tw; /* tag word (16bits) */
long en_fip; /* floating point instruction pointer */
__uint16_t en_fcs; /* floating code segment selector */
__uint16_t en_opcode; /* opcode last executed (11 bits ) */
long en_foo; /* floating operand offset */
long en_fos; /* floating operand segment selector */
};
/* Contents of each floating point accumulator */
struct fpacc87 {
#ifdef dontdef /* too unportable */
__uint32_t fp_mantlo; /* mantissa low (31:0) */
__uint32_t fp_manthi; /* mantissa high (63:32) */
int fp_exp:15; /* exponent */
int fp_sgn:1; /* mantissa sign */
#else
__uint8_t fp_bytes[10];
#endif
};
/* Floating point context */
struct save87 {
struct env87 sv_env; /* floating point control/status */
struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */
#ifndef dontdef
__uint32_t sv_ex_sw; /* status word for last exception (was pad) */
__uint32_t sv_ex_tw; /* tag word for last exception (was pad) */
__uint8_t sv_pad[8 * 2 - 2 * 4]; /* bogus historical padding */
#endif
};
/* Environment of FPU/MMX/SSE/SSE2. */
struct envxmm {
/*0*/ __uint16_t en_cw; /* FPU Control Word */
__uint16_t en_sw; /* FPU Status Word */
__uint8_t en_tw; /* FPU Tag Word (abridged) */
__uint8_t en_rsvd0;
__uint16_t en_opcode; /* FPU Opcode */
__uint32_t en_fip; /* FPU Instruction Pointer */
__uint16_t en_fcs; /* FPU IP selector */
__uint16_t en_rsvd1;
/*16*/ __uint32_t en_foo; /* FPU Data pointer */
__uint16_t en_fos; /* FPU Data pointer selector */
__uint16_t en_rsvd2;
__uint32_t en_mxcsr; /* MXCSR Register State */
__uint32_t en_rsvd3;
};
/* FPU regsters in the extended save format. */
struct fpaccxmm {
__uint8_t fp_bytes[10];
__uint8_t fp_rsvd[6];
};
/* SSE/SSE2 registers. */
struct xmmreg {
__uint8_t sse_bytes[16];
};
/* FPU/MMX/SSE/SSE2 context */
struct savexmm {
struct envxmm sv_env; /* control/status context */
struct fpaccxmm sv_ac[8]; /* ST/MM regs */
struct xmmreg sv_xmmregs[8]; /* XMM regs */
__uint8_t sv_rsvd[16 * 14];
/* 512-bytes --- end of hardware portion of save area */
__uint32_t sv_ex_sw; /* saved SW from last exception */
__uint32_t sv_ex_tw; /* saved TW from last exception */
} __attribute__((__aligned__(16)));
union savefpu {
struct save87 sv_87;
struct savexmm sv_xmm;
};
/*
* The i387 defaults to Intel extended precision mode and round to nearest,
* with all exceptions masked.
*/
#define __INITIAL_NPXCW__ 0x037f
/* NetBSD uses IEEE double precision. */
#define __NetBSD_NPXCW__ 0x127f
/* FreeBSD leaves some exceptions unmasked as well. */
#define __FreeBSD_NPXCW__ 0x1272
/* iBCS2 goes a bit further and leaves the underflow exception unmasked. */
#define __iBCS2_NPXCW__ 0x0262
/* Linux just uses the default control word. */
#define __Linux_NPXCW__ 0x037f
/* SVR4 uses the same control word as iBCS2. */
#define __SVR4_NPXCW__ 0x0262
/*
* The default MXCSR value at reset is 0x1f80, IA-32 Instruction
* Set Reference, pg. 3-369.
*/
#define __INITIAL_MXCSR__ 0x1f80
/*
* 80387 control word bits
*/
#define EN_SW_INVOP 0x0001 /* Invalid operation */
#define EN_SW_DENORM 0x0002 /* Denormalized operand */
#define EN_SW_ZERODIV 0x0004 /* Divide by zero */
#define EN_SW_OVERFLOW 0x0008 /* Overflow */
#define EN_SW_UNDERFLOW 0x0010 /* Underflow */
#define EN_SW_PRECLOSS 0x0020 /* Loss of precision */
#define EN_SW_DATACHAIN 0x0080 /* Data chain exception */
#define EN_SW_CTL_PREC 0x0300 /* Precision control */
#define EN_SW_CTL_ROUND 0x0c00 /* Rounding control */
#define EN_SW_CTL_INF 0x1000 /* Infinity control */
/*
* The standard control word from finit is 0x37F, giving:
* round to nearest
* 64-bit precision
* all exceptions masked.
*
* Now we want:
* affine mode (if we decide to support 287's)
* round to nearest
* 53-bit precision
* all exceptions masked.
*
* 64-bit precision often gives bad results with high level languages
* because it makes the results of calculations depend on whether
* intermediate values are stored in memory or in FPU registers.
*
* The iBCS control word has underflow, overflow, zero divide, and invalid
* operation exceptions unmasked. But that causes an unexpected exception
* in the test program 'paranoia' and makes denormals useless (DBL_MIN / 2
* underflows). It doesn't make a lot of sense to trap underflow without
* trapping denormals.
*/
#ifdef _KERNEL
void probeintr(void);
void probetrap(void);
int npx586bug1(int, int);
void npxinit(struct cpu_info *);
void process_xmm_to_s87(const struct savexmm *, struct save87 *);
void process_s87_to_xmm(const struct save87 *, struct savexmm *);
struct lwp;
int npxtrap(struct lwp *);
#endif
#endif /* !_I386_NPX_H_ */

15
libm/arch/i387/nanf.c Normal file
View File

@ -0,0 +1,15 @@
/* $NetBSD: nanf.c,v 1.4 2009/02/22 01:34:01 martin Exp $ */
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: nanf.c,v 1.4 2009/02/22 01:34:01 martin Exp $");
#endif /* LIBC_SCCS and not lint */
#include <math.h>
#include <machine/endian.h>
/* bytes for quiet NaN (IEEE single precision) */
const union __float_u __nanf =
{ { 0, 0, 0xc0, 0x7f } };
__warn_references(__nanf, "warning: <math.h> defines NAN incorrectly for your compiler.")

18
libm/arch/i387/s_atan.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_atan.S,v 1.6 2003/07/26 19:25:00 salo Exp $")
ENTRY(atan)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE
fld1
fpatan
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/s_atanf.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_atanf.S,v 1.5 2003/07/26 19:25:00 salo Exp $")
ENTRY(atanf)
XMM_ONE_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_ONE
fld1
fpatan
XMM_FLOAT_EPILOGUE
ret

45
libm/arch/i387/s_ceil.S Normal file
View File

@ -0,0 +1,45 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_ceil.S,v 1.8 2011/06/18 21:24:51 joerg Exp $")
ENTRY(ceil)
#ifdef __i386__
pushl %ebp
movl %esp,%ebp
subl $8,%esp
fstcw -4(%ebp) /* store fpu control word */
movw -4(%ebp),%dx
orw $0x0800,%dx /* round towards +oo */
andw $0xfbff,%dx
movw %dx,-8(%ebp)
fldcw -8(%ebp) /* load modfied control word */
fldl 8(%ebp) /* round */
frndint
fldcw -4(%ebp) /* restore original control word */
leave
#else
fstcw -12(%rsp)
movw -12(%rsp),%dx
orw $0x0800,%dx
andw $0xfbff,%dx
movw %dx,-16(%rsp)
fldcw -16(%rsp)
movsd %xmm0,-8(%rsp)
fldl -8(%rsp)
frndint
fldcw -12(%rsp)
fstpl -8(%rsp)
movsd -8(%rsp),%xmm0
#endif
ret

43
libm/arch/i387/s_ceilf.S Normal file
View File

@ -0,0 +1,43 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_ceilf.S,v 1.9 2011/06/18 21:24:51 joerg Exp $")
ENTRY(ceilf)
#ifdef __i386__
pushl %ebp
movl %esp,%ebp
subl $8,%esp
fstcw -4(%ebp) /* store fpu control word */
movw -4(%ebp),%dx
orw $0x0800,%dx /* round towards +oo */
andw $0xfbff,%dx
movw %dx,-8(%ebp)
fldcw -8(%ebp) /* load modfied control word */
flds 8(%ebp) /* round */
frndint
fldcw -4(%ebp) /* restore original control word */
leave
#else
fstcw -8(%rsp)
movw -8(%rsp),%dx
orw $0x0800,%dx
andw $0xfbff,%dx
movw %dx,-12(%rsp)
fldcw -12(%rsp)
movss %xmm0,-4(%rsp)
flds -4(%rsp)
frndint
fldcw -8(%rsp)
fstps -4(%rsp)
movss -4(%rsp),%xmm0
#endif
ret

View File

@ -0,0 +1,38 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
/*
* XXXfvdl might as well split this file.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_copysign.S,v 1.7 2011/06/18 20:49:26 joerg Exp $")
#ifdef __x86_64__
.Lpos:
.quad 0x8000000000000000
.Lneg:
.quad 0x7fffffffffffffff
#endif
ENTRY(copysign)
#ifdef __i386__
movl 16(%esp),%edx
andl $0x80000000,%edx
movl 8(%esp),%eax
andl $0x7fffffff,%eax
orl %edx,%eax
movl %eax,8(%esp)
fldl 4(%esp)
#else
movq .Lpos(%rip),%xmm2
movq .Lneg(%rip),%xmm3
pand %xmm2,%xmm1
pand %xmm3,%xmm0
por %xmm1,%xmm0
#endif
ret

View File

@ -0,0 +1,37 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
/*
* XXXfvdl split this file.
*/
RCSID("$NetBSD: s_copysignf.S,v 1.7 2011/06/21 21:52:49 joerg Exp $")
#ifdef __x86_64__
.Lneg:
.long 0x7fffffff
.Lpos:
.long 0x80000000
#endif
ENTRY(copysignf)
#ifdef __i386__
movl 8(%esp),%edx
andl $0x80000000,%edx
movl 4(%esp),%eax
andl $0x7fffffff,%eax
orl %edx,%eax
movl %eax,4(%esp)
flds 4(%esp)
#else
movss .Lpos(%rip),%xmm2
movss .Lneg(%rip),%xmm3
pand %xmm2,%xmm1
pand %xmm3,%xmm0
por %xmm1,%xmm0
#endif
ret

31
libm/arch/i387/s_cos.S Normal file
View File

@ -0,0 +1,31 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_cos.S,v 1.8 2003/07/26 19:25:01 salo Exp $")
ENTRY(cos)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE
fcos
fnstsw %ax
andw $0x400,%ax
jnz 1f
XMM_DOUBLE_EPILOGUE
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fnstsw %ax
andw $0x400,%ax
jnz 2b
fstp %st(1)
fcos
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/s_cosf.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_cosf.S,v 1.6 2003/07/26 19:25:01 salo Exp $")
/* A float's domain isn't large enough to require argument reduction. */
ENTRY(cosf)
XMM_ONE_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_ONE
fcos
XMM_FLOAT_EPILOGUE
ret

26
libm/arch/i387/s_finite.S Normal file
View File

@ -0,0 +1,26 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_finite.S,v 1.7 2003/07/26 19:25:01 salo Exp $")
ENTRY(finite)
#ifdef __i386__
movl 8(%esp),%eax
andl $0x7ff00000, %eax
cmpl $0x7ff00000, %eax
setne %al
andl $0x000000ff, %eax
#else
xorl %eax,%eax
movq $0x7ff0000000000000,%rsi
movq %rsi,%rdi
movsd %xmm0,-8(%rsp)
andq -8(%rsp),%rsi
cmpq %rdi,%rsi
setne %al
#endif
ret

View File

@ -0,0 +1,25 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_finitef.S,v 1.6 2003/07/26 19:25:01 salo Exp $")
ENTRY(finitef)
#ifdef __i386__
movl 4(%esp),%eax
andl $0x7f800000, %eax
cmpl $0x7f800000, %eax
setne %al
andl $0x000000ff, %eax
#else
xorl %eax,%eax
movl $0x7ff00000,%esi
movss %xmm0,-4(%rsp)
andl -4(%rsp),%esi
cmpl $0x7ff00000,%esi
setne %al
#endif
ret

43
libm/arch/i387/s_floor.S Normal file
View File

@ -0,0 +1,43 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_floor.S,v 1.9 2011/06/18 21:24:51 joerg Exp $")
ENTRY(floor)
#ifdef __i386__
pushl %ebp
movl %esp,%ebp
subl $8,%esp
fstcw -4(%ebp) /* store fpu control word */
movw -4(%ebp),%dx
orw $0x0400,%dx /* round towards -oo */
andw $0xf7ff,%dx
movw %dx,-8(%ebp)
fldcw -8(%ebp) /* load modfied control word */
fldl 8(%ebp) /* round */
frndint
fldcw -4(%ebp) /* restore original control word */
leave
#else
movsd %xmm0, -8(%rsp)
fstcw -12(%rsp)
movw -12(%rsp),%dx
orw $0x0400,%dx
andw $0xf7ff,%dx
movw %dx,-16(%rsp)
fldcw -16(%rsp)
fldl -8(%rsp)
frndint
fldcw -12(%rsp)
fstpl -8(%rsp)
movsd -8(%rsp),%xmm0
#endif
ret

43
libm/arch/i387/s_floorf.S Normal file
View File

@ -0,0 +1,43 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_floorf.S,v 1.8 2011/06/18 21:24:51 joerg Exp $")
ENTRY(floorf)
#ifdef __i386__
pushl %ebp
movl %esp,%ebp
subl $8,%esp
fstcw -4(%ebp) /* store fpu control word */
movw -4(%ebp),%dx
orw $0x0400,%dx /* round towards -oo */
andw $0xf7ff,%dx
movw %dx,-8(%ebp)
fldcw -8(%ebp) /* load modfied control word */
flds 8(%ebp) /* round */
frndint
fldcw -4(%ebp) /* restore original control word */
leave
#else
movss %xmm0, -4(%rsp)
fstcw -8(%rsp)
movw -8(%rsp),%dx
orw $0x0400,%dx
andw $0xf7ff,%dx
movw %dx,-12(%rsp)
fldcw -12(%rsp)
flds -4(%rsp)
frndint
fldcw -8(%rsp)
fstps -4(%rsp)
movss -4(%rsp),%xmm0
#endif
ret

32
libm/arch/i387/s_ilogb.S Normal file
View File

@ -0,0 +1,32 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_ilogb.S,v 1.7 2003/07/26 19:25:02 salo Exp $")
ENTRY(ilogb)
#ifdef __i386__
pushl %ebp
movl %esp,%ebp
subl $4,%esp
fldl 8(%ebp)
fxtract
fstp %st
fistpl -4(%ebp)
movl -4(%ebp),%eax
leave
#else
movsd %xmm0,-8(%rsp)
fldl -8(%rsp)
fxtract
fstp %st
fistpl -8(%rsp)
movl -8(%rsp),%eax
#endif
ret

32
libm/arch/i387/s_ilogbf.S Normal file
View File

@ -0,0 +1,32 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_ilogbf.S,v 1.6 2003/07/26 19:25:02 salo Exp $")
ENTRY(ilogbf)
#ifdef __i386__
pushl %ebp
movl %esp,%ebp
subl $4,%esp
flds 8(%ebp)
fxtract
fstp %st
fistpl -4(%ebp)
movl -4(%ebp),%eax
leave
#else
movss %xmm0,-4(%rsp)
flds -4(%rsp)
fxtract
fstp %st
fistpl -4(%rsp)
movl -4(%rsp),%eax
#endif
ret

24
libm/arch/i387/s_ilogbl.S Normal file
View File

@ -0,0 +1,24 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_ilogbl.S,v 1.1 2011/07/28 22:32:28 joerg Exp $")
#include "abi.h"
ENTRY(ilogbl)
fldt ARG_LONG_DOUBLE_ONE
fxtract
fstp %st
#ifdef __i386__
pushl %eax
fistpl 0(%esp)
popl %eax
#else
fistpl -4(%rsp)
movl -4(%rsp), %eax
#endif
ret

76
libm/arch/i387/s_log1p.S Normal file
View File

@ -0,0 +1,76 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
/*
* Modified by Lex Wennmacher <wennmach@NetBSD.org>
* Still public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_log1p.S,v 1.13 2003/09/16 18:17:11 wennmach Exp $")
/*
* The log1p() function is provided to compute an accurate value of
* log(1 + x), even for tiny values of x. The i387 FPU provides the
* fyl2xp1 instruction for this purpose. However, the range of this
* instruction is limited to:
* -(1 - (sqrt(2) / 2)) <= x <= sqrt(2) - 1
* -0.292893 <= x <= 0.414214
* at least on older processor versions.
*
* log1p() is implemented by testing the range of the argument.
* If it is appropriate for fyl2xp1, this instruction is used.
* Else, we compute log1p(x) = ln(2)*ld(1 + x) the traditional way
* (using fyl2x).
*
* The range testing costs speed, but as the rationale for the very
* existence of this function is accuracy, we accept that.
*
* In order to reduce the cost for testing the range, we check if
* the argument is in the range
* -0.25 <= x <= 0.25
* which can be done with just one conditional branch. If x is
* inside this range, we use fyl2xp1. Outside of this range,
* the use of fyl2x is accurate enough.
*
*/
.text
.align 4
ENTRY(log1p)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE
fabs
fld1 /* ... x 1 */
fadd %st(0) /* ... x 2 */
fadd %st(0) /* ... x 4 */
fld1 /* ... 4 1 */
fdivp /* ... x 0.25 */
fcompp
fnstsw %ax
andb $69,%ah
jne use_fyl2x
jmp use_fyl2xp1
.align 4
use_fyl2x:
fldln2
fldl ARG_DOUBLE_ONE
fld1
faddp
fyl2x
XMM_DOUBLE_EPILOGUE
ret
.align 4
use_fyl2xp1:
fldln2
fldl ARG_DOUBLE_ONE
fyl2xp1
XMM_DOUBLE_EPILOGUE
ret

76
libm/arch/i387/s_log1pf.S Normal file
View File

@ -0,0 +1,76 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
/*
* Modified by Lex Wennmacher <wennmach@NetBSD.org>
* Still public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_log1pf.S,v 1.10 2003/09/16 18:17:11 wennmach Exp $")
/*
* The log1pf() function is provided to compute an accurate value of
* log(1 + x), even for tiny values of x. The i387 FPU provides the
* fyl2xp1 instruction for this purpose. However, the range of this
* instruction is limited to:
* -(1 - (sqrt(2) / 2)) <= x <= sqrt(2) - 1
* -0.292893 <= x <= 0.414214
* at least on older processor versions.
*
* log1pf() is implemented by testing the range of the argument.
* If it is appropriate for fyl2xp1, this instruction is used.
* Else, we compute log1pf(x) = ln(2)*ld(1 + x) the traditional way
* (using fyl2x).
*
* The range testing costs speed, but as the rationale for the very
* existence of this function is accuracy, we accept that.
*
* In order to reduce the cost for testing the range, we check if
* the argument is in the range
* -0.25 <= x <= 0.25
* which can be done with just one conditional branch. If x is
* inside this range, we use fyl2xp1. Outside of this range,
* the use of fyl2x is accurate enough.
*
*/
.text
.align 4
ENTRY(log1pf)
XMM_ONE_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_ONE
fabs
fld1 /* ... x 1 */
fadd %st(0) /* ... x 2 */
fadd %st(0) /* ... x 4 */
fld1 /* ... 4 1 */
fdivp /* ... x 0.25 */
fcompp
fnstsw %ax
andb $69,%ah
jne use_fyl2x
jmp use_fyl2xp1
.align 4
use_fyl2x:
fldln2
flds ARG_FLOAT_ONE
fld1
faddp
fyl2x
XMM_FLOAT_EPILOGUE
ret
.align 4
use_fyl2xp1:
fldln2
flds ARG_FLOAT_ONE
fyl2xp1
XMM_FLOAT_EPILOGUE
ret

18
libm/arch/i387/s_logb.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_logb.S,v 1.6 2003/07/26 19:25:02 salo Exp $")
ENTRY(logb)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE
fxtract
fstp %st
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/s_logbf.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_logbf.S,v 1.5 2003/07/26 19:25:02 salo Exp $")
ENTRY(logbf)
XMM_ONE_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_ONE
fxtract
fstp %st
XMM_FLOAT_EPILOGUE
ret

16
libm/arch/i387/s_logbl.S Normal file
View File

@ -0,0 +1,16 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_logbl.S,v 1.1 2011/08/03 14:13:07 joerg Exp $")
ENTRY(logbl)
fldt ARG_LONG_DOUBLE_ONE
fxtract
fstp %st
ret

106
libm/arch/i387/s_modf.S Normal file
View File

@ -0,0 +1,106 @@
/* $NetBSD: s_modf.S,v 1.1 2006/03/22 20:45:58 drochner Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Sean Eric Fagan.
*
* 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
* from: @(#)modf.s 5.5 (Berkeley) 3/18/91
*/
#include <machine/asm.h>
#if defined(LIBC_SCCS)
RCSID("$NetBSD: s_modf.S,v 1.1 2006/03/22 20:45:58 drochner Exp $")
#endif
/*
* modf(value, iptr): return fractional part of value, and stores the
* integral part into iptr (a pointer to double).
*
* Written by Sean Eric Fagan (sef@kithrup.COM)
* Sun Mar 11 20:27:30 PST 1990
*/
/* With CHOP mode on, frndint behaves as TRUNC does. Useful. */
ENTRY(modf)
#ifdef __x86_64__
pushq %rbp
movq %rsp,%rbp
subq $24,%rsp
/* Set chop mode. */
fnstcw -12(%rbp)
movw -12(%rbp),%dx
orw $3072,%dx
movw %dx,-16(%rbp)
fldcw -16(%rbp)
/* Get integral part. */
movsd %xmm0,-24(%rbp)
fldl -24(%rbp)
frndint
fstpl -8(%rbp)
/* Restore control word. */
fldcw -12(%rbp)
/* Store integral part. */
movsd -8(%rbp),%xmm0
movsd %xmm0,(%rdi)
/* Get fractional part and return it. */
fldl -24(%rbp)
fsubl -8(%rbp)
fstpl -24(%rbp)
movsd -24(%rbp),%xmm0
#else
pushl %ebp
movl %esp,%ebp
subl $16,%esp
fnstcw -12(%ebp)
movw -12(%ebp),%dx
orw $3072,%dx
movw %dx,-16(%ebp)
fldcw -16(%ebp)
fldl 8(%ebp)
frndint
fstpl -8(%ebp)
fldcw -12(%ebp)
movl 16(%ebp),%eax
movl -8(%ebp),%edx
movl -4(%ebp),%ecx
movl %edx,(%eax)
movl %ecx,4(%eax)
fldl 8(%ebp)
fsubl -8(%ebp)
jmp L1
L1:
#endif
leave
ret

17
libm/arch/i387/s_rint.S Normal file
View File

@ -0,0 +1,17 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_rint.S,v 1.6 2003/07/26 19:25:03 salo Exp $")
ENTRY(rint)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE
frndint
XMM_DOUBLE_EPILOGUE
ret

17
libm/arch/i387/s_rintf.S Normal file
View File

@ -0,0 +1,17 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_rintf.S,v 1.5 2003/07/26 19:25:03 salo Exp $")
ENTRY(rintf)
XMM_ONE_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_ONE
frndint
XMM_FLOAT_EPILOGUE
ret

30
libm/arch/i387/s_scalbn.S Normal file
View File

@ -0,0 +1,30 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_scalbn.S,v 1.9 2010/04/23 19:17:07 drochner Exp $")
#ifdef WEAK_ALIAS
WEAK_ALIAS(scalbn,_scalbn)
#endif
ENTRY(_scalbn)
#ifdef __x86_64__
movl %edi,-12(%rsp)
fildl -12(%rsp)
movsd %xmm0,-8(%rsp)
fldl -8(%rsp)
fscale
fstpl -8(%rsp)
movsd -8(%rsp),%xmm0
fstp %st(0)
#else
fildl 12(%esp)
fldl 4(%esp)
fscale
fstp %st(1) /* clean up stack */
#endif
ret

View File

@ -0,0 +1,30 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_scalbnf.S,v 1.8 2010/04/23 19:17:07 drochner Exp $")
#ifdef WEAK_ALIAS
WEAK_ALIAS(scalbnf,_scalbnf)
#endif
ENTRY(_scalbnf)
#ifdef __x86_64__
movl %edi,-8(%rsp)
fildl -8(%rsp)
movss %xmm0,-4(%rsp)
flds -4(%rsp)
fscale
fstps -4(%rsp)
movss -4(%rsp),%xmm0
fstp %st(0)
#else
fildl 8(%esp)
flds 4(%esp)
fscale
fstp %st(1) /* clean up stack */
#endif
ret

View File

@ -0,0 +1,27 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_scalbnl.S,v 1.1 2011/07/26 17:03:23 joerg Exp $")
#ifdef WEAK_ALIAS
WEAK_ALIAS(scalbnl,_scalbnl)
#endif
ENTRY(_scalbnl)
#ifdef __x86_64__
movl %edi,-4(%rsp)
fildl -4(%rsp)
fldt 8(%rsp)
fscale
fstp %st(1)
#else
fildl 16(%esp)
fldt 4(%esp)
fscale
fstp %st(1) /* clean up stack */
#endif
ret

View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_significand.S,v 1.6 2003/07/26 19:25:03 salo Exp $")
ENTRY(significand)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE
fxtract
fstp %st(1)
XMM_DOUBLE_EPILOGUE
ret

View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_significandf.S,v 1.5 2003/07/26 19:25:03 salo Exp $")
ENTRY(significandf)
XMM_ONE_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_ONE
fxtract
fstp %st(1)
XMM_FLOAT_EPILOGUE
ret

31
libm/arch/i387/s_sin.S Normal file
View File

@ -0,0 +1,31 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_sin.S,v 1.7 2003/07/26 19:25:03 salo Exp $")
ENTRY(sin)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE
fsin
fnstsw %ax
andw $0x400,%ax
jnz 1f
XMM_DOUBLE_EPILOGUE
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fnstsw %ax
andw $0x400,%ax
jnz 2b
fstp %st(1)
fsin
XMM_DOUBLE_EPILOGUE
ret

18
libm/arch/i387/s_sinf.S Normal file
View File

@ -0,0 +1,18 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_sinf.S,v 1.5 2003/07/26 19:25:04 salo Exp $")
/* A float's domain isn't large enough to require argument reduction. */
ENTRY(sinf)
XMM_ONE_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_ONE
fsin
XMM_FLOAT_EPILOGUE
ret

33
libm/arch/i387/s_tan.S Normal file
View File

@ -0,0 +1,33 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_tan.S,v 1.7 2003/07/26 19:25:04 salo Exp $")
ENTRY(tan)
XMM_ONE_ARG_DOUBLE_PROLOGUE
fldl ARG_DOUBLE_ONE
fptan
fnstsw %ax
andw $0x400,%ax
jnz 1f
fstp %st(0)
XMM_DOUBLE_EPILOGUE
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fstsw %ax
andw $0x400,%ax
jnz 2b
fstp %st(1)
fptan
fstp %st(0)
XMM_DOUBLE_EPILOGUE
ret

19
libm/arch/i387/s_tanf.S Normal file
View File

@ -0,0 +1,19 @@
/*
* Written by J.T. Conklin <jtc@NetBSD.org>.
* Public domain.
*/
#include <machine/asm.h>
#include "abi.h"
RCSID("$NetBSD: s_tanf.S,v 1.5 2003/07/26 19:25:04 salo Exp $")
/* A float's domain isn't large enough to require argument reduction. */
ENTRY(tanf)
XMM_ONE_ARG_FLOAT_PROLOGUE
flds ARG_FLOAT_ONE
fptan
fstp %st(0)
XMM_FLOAT_EPILOGUE
ret

1
libm/arch/x86_64/abi.h Symbolic link
View File

@ -0,0 +1 @@
../i387/abi.h

1
libm/arch/x86_64/e_acos.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_acos.S

1
libm/arch/x86_64/e_asin.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_asin.S

1
libm/arch/x86_64/e_atan2.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_atan2.S

1
libm/arch/x86_64/e_atan2f.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_atan2f.S

1
libm/arch/x86_64/e_exp.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_exp.S

1
libm/arch/x86_64/e_expf.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_expf.S

1
libm/arch/x86_64/e_fmod.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_fmod.S

1
libm/arch/x86_64/e_log.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_log.S

1
libm/arch/x86_64/e_log10.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_log10.S

1
libm/arch/x86_64/e_log10f.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_log10f.S

1
libm/arch/x86_64/e_log2.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_log2.S

1
libm/arch/x86_64/e_log2f.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_log2f.S

1
libm/arch/x86_64/e_logf.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_logf.S

View File

@ -0,0 +1 @@
../i387/e_remainder.S

View File

@ -0,0 +1 @@
../i387/e_remainderf.S

1
libm/arch/x86_64/e_scalb.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_scalb.S

1
libm/arch/x86_64/e_scalbf.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_scalbf.S

1
libm/arch/x86_64/e_sqrt.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_sqrt.S

1
libm/arch/x86_64/e_sqrtf.S Symbolic link
View File

@ -0,0 +1 @@
../i387/e_sqrtf.S

17
libm/arch/x86_64/fabs.S Normal file
View File

@ -0,0 +1,17 @@
/* $NetBSD: fabs.S,v 1.3 2004/03/23 17:11:35 drochner Exp $ */
#include <machine/asm.h>
#if defined(LIBC_SCCS)
RCSID("$NetBSD: fabs.S,v 1.3 2004/03/23 17:11:35 drochner Exp $")
#endif
.section .rodata
.align 8
__signmask:
.long 0xffffffff
.long 0x7fffffff
ENTRY(fabs)
movsd __signmask(%rip),%xmm1
andpd %xmm1,%xmm0
ret

531
libm/arch/x86_64/fenv.c Normal file
View File

@ -0,0 +1,531 @@
/* $NetBSD: fenv.c,v 1.1.8.1.6.1 2013/06/14 02:43:36 msaitoh Exp $ */
/*-
* Copyright (c) 2004-2005 David Schultz <das (at) 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 <sys/cdefs.h>
__RCSID("$NetBSD: fenv.c,v 1.1.8.1.6.1 2013/06/14 02:43:36 msaitoh Exp $");
#include <assert.h>
#include <fenv.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
/* Load x87 Control Word */
#define __fldcw(__cw) __asm__ __volatile__ \
("fldcw %0" : : "m" (__cw))
/* No-Wait Store Control Word */
#define __fnstcw(__cw) __asm__ __volatile__ \
("fnstcw %0" : "=m" (*(__cw)))
/* No-Wait Store Status Word */
#define __fnstsw(__sw) __asm__ __volatile__ \
("fnstsw %0" : "=am" (*(__sw)))
/* No-Wait Clear Exception Flags */
#define __fnclex() __asm__ __volatile__ \
("fnclex")
/* Load x87 Environment */
#define __fldenv(__env) __asm__ __volatile__ \
("fldenv %0" : : "m" (__env))
/* No-Wait Store x87 environment */
#define __fnstenv(__env) __asm__ __volatile__ \
("fnstenv %0" : "=m" (*(__env)))
/* Check for and handle pending unmasked x87 pending FPU exceptions */
#define __fwait(__env) __asm__ __volatile__ \
("fwait")
/* Load the MXCSR register */
#define __ldmxcsr(__mxcsr) __asm__ __volatile__ \
("ldmxcsr %0" : : "m" (__mxcsr))
/* Store the MXCSR register state */
#define __stmxcsr(__mxcsr) __asm__ __volatile__ \
("stmxcsr %0" : "=m" (*(__mxcsr)))
/*
* The following constant represents the default floating-point environment
* (that is, the one installed at program startup) and has type pointer to
* const-qualified fenv_t.
*
* It can be used as an argument to the functions within the <fenv.h> header
* that manage the floating-point environment, namely fesetenv() and
* feupdateenv().
*
* x87 fpu registers are 16bit wide. The upper bits, 31-16, are marked as
* RESERVED. We provide a partial floating-point environment, where we
* define only the lower bits. The reserved bits are extracted and set by
* the consumers of FE_DFL_ENV, during runtime.
*/
fenv_t __fe_dfl_env = {
{
__NetBSD_NPXCW__, /* Control word register */
0x00000000, /* Status word register */
0x0000ffff, /* Tag word register */
{
0x00000000,
0x00000000,
0x00000000,
0x00000000,
},
},
__INITIAL_MXCSR__ /* MXCSR register */
};
#define FE_DFL_ENV ((const fenv_t *) &__fe_dfl_env)
/*
* The feclearexcept() function clears the supported floating-point exceptions
* represented by `excepts'.
*/
int
feclearexcept(int excepts)
{
fenv_t fenv;
int ex;
assert((excepts & ~FE_ALL_EXCEPT) == 0);
ex = excepts & FE_ALL_EXCEPT;
/* Store the current x87 floating-point environment */
__fnstenv(&fenv);
/* Clear the requested floating-point exceptions */
fenv.x87.status &= ~ex;
/* Load the x87 floating-point environent */
__fldenv(fenv);
/* Same for SSE environment */
__stmxcsr(&fenv.mxcsr);
fenv.mxcsr &= ~ex;
__ldmxcsr(fenv.mxcsr);
/* Success */
return (0);
}
/*
* The fegetexceptflag() function stores an implementation-defined
* representation of the states of the floating-point status flags indicated by
* the argument excepts in the object pointed to by the argument flagp.
*/
int
fegetexceptflag(fexcept_t *flagp, int excepts)
{
uint32_t mxcsr;
uint16_t x87_status;
int ex;
assert(flagp != NULL);
assert((excepts & ~FE_ALL_EXCEPT) == 0);
ex = excepts & FE_ALL_EXCEPT;
/* Store the current x87 status register */
__fnstsw(&x87_status);
/* Store the MXCSR register */
__stmxcsr(&mxcsr);
/* Store the results in flagp */
*flagp = (x87_status | mxcsr) & ex;
/* Success */
return (0);
}
/*
* The feraiseexcept() function raises the supported floating-point exceptions
* represented by the argument `excepts'.
*
* The standard explicitly allows us to execute an instruction that has the
* exception as a side effect, but we choose to manipulate the status register
* directly.
*
* The validation of input is being deferred to fesetexceptflag().
*/
int
feraiseexcept(int excepts)
{
int ex;
assert((excepts & ~FE_ALL_EXCEPT) == 0);
ex = excepts & FE_ALL_EXCEPT;
fesetexceptflag((unsigned int *)&excepts, excepts);
__fwait();
(void) ex;
/* Success */
return (0);
}
/*
* This function sets the floating-point status flags indicated by the argument
* `excepts' to the states stored in the object pointed to by `flagp'. It does
* NOT raise any floating-point exceptions, but only sets the state of the flags.
*/
int
fesetexceptflag(const fexcept_t *flagp, int excepts)
{
fenv_t fenv;
int ex;
assert(flagp != NULL);
assert((excepts & ~FE_ALL_EXCEPT) == 0);
ex = excepts & FE_ALL_EXCEPT;
/* Store the current x87 floating-point environment */
__fnstenv(&fenv);
/* Set the requested status flags */
fenv.x87.status |= *flagp & ex;
/* Load the x87 floating-point environent */
__fldenv(fenv);
/* Same for SSE environment */
__stmxcsr(&fenv.mxcsr);
fenv.mxcsr |= *flagp & ex;
__ldmxcsr(fenv.mxcsr);
/* Success */
return (0);
}
/*
* The fetestexcept() function determines which of a specified subset of the
* floating-point exception flags are currently set. The `excepts' argument
* specifies the floating-point status flags to be queried.
*/
int
fetestexcept(int excepts)
{
fenv_t fenv;
uint32_t mxcsr;
uint16_t status;
int ex;
assert((excepts & ~FE_ALL_EXCEPT) == 0);
ex = excepts & FE_ALL_EXCEPT;
/* Store the current x87 floating-point environment */
memset(&fenv, 0, sizeof(fenv));
__fnstenv(&fenv);
__fnstsw(&status);
/* Store the MXCSR register state */
__stmxcsr(&fenv.mxcsr);
__stmxcsr(&mxcsr);
return ((fenv.x87.status | fenv.mxcsr) & ex);
}
/*
* The fegetround() function gets the current rounding direction.
*/
int
fegetround(void)
{
uint32_t mxcsr;
uint16_t control;
/*
* We check both the x87 floating-point unit _and_ the SSE unit.
* Normally, those two must agree with respect to each other. If they
* don't, it's not our fault and the result is non-determinable, in
* which case POSIX says that a negative value should be returned.
*/
__fnstcw(&control);
__stmxcsr(&mxcsr);
if ((control & _X87_ROUNDING_MASK)
!= ((mxcsr & _SSE_ROUNDING_MASK) >> 3)) {
return (-1);
}
return (control & _X87_ROUNDING_MASK);
}
/*
* The fesetround() function establishes the rounding direction represented by
* its argument `round'. If the argument is not equal to the value of a rounding
* direction macro, the rounding direction is not changed.
*/
int
fesetround(int round)
{
uint32_t mxcsr;
uint16_t control;
/* Check whether requested rounding direction is supported */
if (round & (~_X87_ROUNDING_MASK))
return (-1);
/* Store the current x87 control word register */
__fnstcw(&control);
/*
* Set the rounding direction
* Rounding Control is bits 10-11, so shift appropriately
*/
control &= ~_X87_ROUNDING_MASK;
control |= round;
/* Load the x87 control word register */
__fldcw(control);
/*
* Same for the SSE environment
* Rounding Control is bits 13-14, so shift appropriately
*/
__stmxcsr(&mxcsr);
mxcsr &= ~_SSE_ROUNDING_MASK;
mxcsr |= (round << _SSE_ROUND_SHIFT);
__ldmxcsr(mxcsr);
/* Success */
return (0);
}
/*
* The fegetenv() function attempts to store the current floating-point
* environment in the object pointed to by envp.
*/
int
fegetenv(fenv_t *envp)
{
assert(envp != NULL);
/* Store the current x87 floating-point environment */
__fnstenv(envp);
/* Store the MXCSR register state */
__stmxcsr(&envp->mxcsr);
/*
* When an FNSTENV instruction is executed, all pending exceptions are
* essentially lost (either the x87 FPU status register is cleared or all
* exceptions are masked).
*
* 8.6 X87 FPU EXCEPTION SYNCHRONIZATION -
* Intel(R) 64 and IA-32 Architectures Softare Developer's Manual - Vol 1
*
*/
__fldcw(envp->x87.control);
/* Success */
return (0);
}
/*
* The feholdexcept() function saves the current floating-point environment
* in the object pointed to by envp, clears the floating-point status flags, and
* then installs a non-stop (continue on floating-point exceptions) mode, if
* available, for all floating-point exceptions.
*/
int
feholdexcept(fenv_t *envp)
{
uint32_t mxcsr;
assert(envp != NULL);
/* Store the current x87 floating-point environment */
__fnstenv(envp);
/* Clear all exception flags in FPU */
__fnclex();
/* Store the MXCSR register state */
__stmxcsr(&envp->mxcsr);
/* Clear exception flags in MXCSR XXX */
mxcsr = envp->mxcsr;
mxcsr &= ~FE_ALL_EXCEPT;
/* Mask all exceptions */
mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT;
__ldmxcsr(mxcsr);
/* Success */
return (0);
}
/*
* The fesetenv() function attempts to establish the floating-point environment
* represented by the object pointed to by envp. The argument `envp' points
* to an object set by a call to fegetenv() or feholdexcept(), or equal a
* floating-point environment macro. The fesetenv() function does not raise
* floating-point exceptions, but only installs the state of the floating-point
* status flags represented through its argument.
*/
int
fesetenv(const fenv_t *envp)
{
fenv_t fenv;
assert(envp != NULL);
/* Store the x87 floating-point environment */
memset(&fenv, 0, sizeof fenv);
__fnstenv(&fenv);
__fe_dfl_env.x87.control = (fenv.x87.control & 0xffff0000)
| (__fe_dfl_env.x87.control & 0x0000ffff);
__fe_dfl_env.x87.status = (fenv.x87.status & 0xffff0000)
| (__fe_dfl_env.x87.status & 0x0000ffff);
__fe_dfl_env.x87.tag = (fenv.x87.tag & 0xffff0000)
| (__fe_dfl_env.x87.tag & 0x0000ffff);
__fe_dfl_env.x87.others[3] = (fenv.x87.others[3] & 0xffff0000)
| (__fe_dfl_env.x87.others[3] & 0x0000ffff);
__fldenv(*envp);
/* Store the MXCSR register */
__ldmxcsr(envp->mxcsr);
/* Success */
return (0);
}
/*
* The feupdateenv() function saves the currently raised floating-point
* exceptions in its automatic storage, installs the floating-point environment
* represented by the object pointed to by `envp', and then raises the saved
* floating-point exceptions. The argument `envp' shall point to an object set
* by a call to feholdexcept() or fegetenv(), or equal a floating-point
* environment macro.
*/
int
feupdateenv(const fenv_t *envp)
{
fenv_t fenv;
uint32_t mxcsr;
uint16_t sw;
assert(envp != NULL);
/* Store the x87 floating-point environment */
memset(&fenv, 0, sizeof(fenv));
__fnstenv(&fenv);
__fe_dfl_env.x87.control = (fenv.x87.control & 0xffff0000)
| (__fe_dfl_env.x87.control & 0x0000ffff);
__fe_dfl_env.x87.status = (fenv.x87.status & 0xffff0000)
| (__fe_dfl_env.x87.status & 0x0000ffff);
__fe_dfl_env.x87.tag = (fenv.x87.tag & 0xffff0000)
| (__fe_dfl_env.x87.tag & 0x0000ffff);
__fe_dfl_env.x87.others[3] = (fenv.x87.others[3] & 0xffff0000)
| (__fe_dfl_env.x87.others[3] & 0x0000ffff);
/* Store the x87 status register */
__fnstsw(&sw);
/* Store the MXCSR register */
__stmxcsr(&mxcsr);
/* Install new floating-point environment */
fesetenv(envp);
/* Raise any previously accumulated exceptions */
feraiseexcept((sw | mxcsr) & FE_ALL_EXCEPT);
/* Success */
return (0);
}
/*
* The following functions are extentions to the standard
*/
int
feenableexcept(int mask)
{
uint32_t mxcsr, omask;
uint16_t control;
assert((mask & ~FE_ALL_EXCEPT) == 0);
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 (FE_ALL_EXCEPT & ~omask);
}
int
fedisableexcept(int mask)
{
uint32_t mxcsr, omask;
uint16_t control;
assert((mask & ~FE_ALL_EXCEPT) == 0);
__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 (FE_ALL_EXCEPT & ~omask);
}
int
fegetexcept(void)
{
uint16_t control;
/*
* We assume that the masks for the x87 and the SSE unit are
* the same.
*/
__fnstcw(&control);
return (~control & FE_ALL_EXCEPT);
}

View File

@ -0,0 +1,21 @@
/* $NetBSD: flt_rounds.S,v 1.6 2011/09/30 17:42:34 christos Exp $ */
#include <machine/asm.h>
/*
* 00 0 round to zero
* 01 1 round to nearest
* 10 2 round to positive infinity
* 11 3 round to negative infinity
*/
.text
_ALIGN_TEXT
ENTRY(__flt_rounds)
fnstcw -4(%rsp)
movl -4(%rsp), %ecx
shrl $9, %ecx
andl $6, %ecx
movl $0x2d, %eax /* 0x2d = 00.10.11.01 */
sarl %cl, %eax /* 0,1,2,3 -> 1,3,2,0 */
andl $3, %eax
ret

View File

@ -0,0 +1,26 @@
/* $NetBSD: fpgetmask.S,v 1.3 2002/06/12 19:17:22 fvdl Exp $ */
/*
* Written by J.T. Conklin, Apr 4, 1995
* Public domain.
*/
#include <machine/asm.h>
/*
* XXX only read x87 control word here. If an application only
* uses the fp* interface to manipulate FP bits, it should
* always remain in sync with the SSE mxcsr register.
*/
#ifdef WEAK_ALIAS
WEAK_ALIAS(fpgetmask, _fpgetmask)
ENTRY(_fpgetmask)
#else
ENTRY(fpgetmask)
#endif
fnstcw -4(%rsp)
movl -4(%rsp),%eax
notl %eax
andl $63,%eax
ret

Some files were not shown because too many files have changed in this diff Show More