Select between the generic math functions and the i387-specific ones

at runtime.

etc/make.conf:
Nuked HAVE_FPU option.

lib/msun/Makefile:
Always build the i387 objects.  Copy the i387 source files at build
time so that the i387 objects have different names.  This is simpler
than renaming the files in the cvs repository or repeating half of
bsd.lib.mk to add explicit rules.

lib/msun/src/*.c:
Renamed all functions that have an i387-specific version by adding
`__generic_' to their names.

lib/msun/src/get_hw_float.c:
New file for getting machdep.hw_float from the kernel.

sys/i386/include/asmacros.h:
Abuse the ENTRY() macro to generate jump vectors and associated code.
This works much like PIC PLT dynamic initialization.  The PIC case is
messy.  The old i387 entry points are renamed.  Renaming is easier
here because the names are given by macro expansions.
This commit is contained in:
bde 1997-02-16 18:26:31 +00:00
parent 85bd6daaf1
commit 9e8f1bd4ec
30 changed files with 264 additions and 74 deletions

View File

@ -31,12 +31,6 @@
#WANT_CSRG_LIBM= yes
#
#
# If you have a FPU (i387, i486DX, Pentium), you can make
# the Sun libm use the FPU:
#
#HAVE_FPU= yes
#
#
# If you do not want unformatted manual pages to be compressed
# when they are installed:
#

View File

@ -31,12 +31,6 @@
#WANT_CSRG_LIBM= yes
#
#
# If you have a FPU (i387, i486DX, Pentium), you can make
# the Sun libm use the FPU:
#
#HAVE_FPU= yes
#
#
# If you do not want unformatted manual pages to be compressed
# when they are installed:
#

View File

@ -41,9 +41,7 @@
# default standard
#
# Enable if you have a i387 (or i486 or Pentium)
.if defined(HAVE_FPU)
.PATH: ${.CURDIR}/i387
ARCH= i387
ARCH_SRCS = e_acos.S e_asin.S e_atan2.S e_exp.S e_fmod.S e_log.S e_log10.S \
e_remainder.S e_scalb.S e_sqrt.S s_atan.S s_ceil.S s_copysign.S \
s_cos.S s_finite.S s_floor.S s_ilogb.S s_logb.S \
@ -51,7 +49,6 @@ ARCH_SRCS = e_acos.S e_asin.S e_atan2.S e_exp.S e_fmod.S e_log.S e_log10.S \
# Broken
# ARCH_SRCS+= s_log1p.S
.endif
.PATH: ${.CURDIR}/man
.PATH: ${.CURDIR}/src
@ -67,6 +64,7 @@ COMMON_SRCS = e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_asin.c e_asinf.c \
e_log.c e_log10.c e_log10f.c e_logf.c e_pow.c e_powf.c e_rem_pio2.c \
e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c e_scalbf.c \
e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c \
get_hw_float.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 \
s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_cbrt.c s_cbrtf.c s_ceil.c \
@ -90,12 +88,18 @@ COMMON_SRCS = e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_asin.c e_asinf.c \
# FreeBSD's C library supplies these functions:
#COMMON_SRCS+= s_fabs.c s_frexp.c s_isnan.c s_ldexp.c s_modf.c
CLEANFILES+= ${RENAMED_ARCH_SRCS}
RENAMED_ARCH_SRCS= ${ARCH_SRCS:S/^/${ARCH}_/g}
SRCS= ${COMMON_SRCS} ${RENAMED_ARCH_SRCS}
SRCS=${COMMON_SRCS}
# Substitute common sources with any arch specific sources
# Generate rules to rename arch-specific sources to avoid conflicts.
# The path to the arch-specific sources is given explicitly instead of
# with `.PATH: ${.CURDIR}/${ARCH}' since otherwise bsd.lib.mk would
# use .S.o rules instead of .c.o rules for the conflicting prefixes
# (except after `make depend' it uses the correct rules!).
.for i in ${ARCH_SRCS}
SRCS:=${SRCS:S/${i:S/.S/.c/}/$i/}
${ARCH}_${i}: ${.CURDIR}/i387/${i}
cp ${.ALLSRC} ${.TARGET}
.endfor
MANSRC= ${.CURDIR}/man

View File

@ -62,9 +62,9 @@ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
#ifdef __STDC__
double __ieee754_acos(double x)
double __generic___ieee754_acos(double x)
#else
double __ieee754_acos(x)
double __generic___ieee754_acos(x)
double x;
#endif
{

View File

@ -71,9 +71,9 @@ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
#ifdef __STDC__
double __ieee754_asin(double x)
double __generic___ieee754_asin(double x)
#else
double __ieee754_asin(x)
double __generic___ieee754_asin(x)
double x;
#endif
{

View File

@ -57,9 +57,9 @@ pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
#ifdef __STDC__
double __ieee754_atan2(double y, double x)
double __generic___ieee754_atan2(double y, double x)
#else
double __ieee754_atan2(y,x)
double __generic___ieee754_atan2(y,x)
double y,x;
#endif
{

View File

@ -104,9 +104,9 @@ P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
#ifdef __STDC__
double __ieee754_exp(double x) /* default IEEE double exp */
double __generic___ieee754_exp(double x) /* default IEEE double exp */
#else
double __ieee754_exp(x) /* default IEEE double exp */
double __generic___ieee754_exp(x) /* default IEEE double exp */
double x;
#endif
{

View File

@ -30,9 +30,9 @@ static double one = 1.0, Zero[] = {0.0, -0.0,};
#endif
#ifdef __STDC__
double __ieee754_fmod(double x, double y)
double __generic___ieee754_fmod(double x, double y)
#else
double __ieee754_fmod(x,y)
double __generic___ieee754_fmod(x,y)
double x,y ;
#endif
{

View File

@ -91,9 +91,9 @@ static double zero = 0.0;
#endif
#ifdef __STDC__
double __ieee754_log(double x)
double __generic___ieee754_log(double x)
#else
double __ieee754_log(x)
double __generic___ieee754_log(x)
double x;
#endif
{

View File

@ -67,9 +67,9 @@ static double zero = 0.0;
#endif
#ifdef __STDC__
double __ieee754_log10(double x)
double __generic___ieee754_log10(double x)
#else
double __ieee754_log10(x)
double __generic___ieee754_log10(x)
double x;
#endif
{

View File

@ -34,9 +34,9 @@ static double zero = 0.0;
#ifdef __STDC__
double __ieee754_remainder(double x, double p)
double __generic___ieee754_remainder(double x, double p)
#else
double __ieee754_remainder(x,p)
double __generic___ieee754_remainder(x,p)
double x,p;
#endif
{

View File

@ -25,16 +25,16 @@ static char rcsid[] = "$FreeBSD$";
#ifdef _SCALB_INT
#ifdef __STDC__
double __ieee754_scalb(double x, int fn)
double __generic___ieee754_scalb(double x, int fn)
#else
double __ieee754_scalb(x,fn)
double __generic___ieee754_scalb(x,fn)
double x; int fn;
#endif
#else
#ifdef __STDC__
double __ieee754_scalb(double x, double fn)
double __generic___ieee754_scalb(double x, double fn)
#else
double __ieee754_scalb(x,fn)
double __generic___ieee754_scalb(x,fn)
double x, fn;
#endif
#endif

View File

@ -94,9 +94,9 @@ static double one = 1.0, tiny=1.0e-300;
#endif
#ifdef __STDC__
double __ieee754_sqrt(double x)
double __generic___ieee754_sqrt(double x)
#else
double __ieee754_sqrt(x)
double __generic___ieee754_sqrt(x)
double x;
#endif
{

View File

@ -0,0 +1,50 @@
/*-
* Copyright (c) 1997 Bruce D. Evans
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/types.h>
#include <sys/sysctl.h>
int __get_hw_float __P((void));
static int hw_float = -1;
int
__get_hw_float()
{
size_t len;
int mib[2];
if (hw_float == -1) {
len = sizeof(hw_float);
mib[0] = CTL_HW;
mib[1] = HW_FLOATINGPT;
if (__sysctl(mib, 2, &hw_float, &len, (void *)0, 0) == -1)
hw_float = 0; /* shouldn't happen; assume the worst */
}
return (hw_float);
}

View File

@ -86,9 +86,9 @@ one = 1.0,
huge = 1.0e300;
#ifdef __STDC__
double atan(double x)
double __generic_atan(double x)
#else
double atan(x)
double __generic_atan(x)
double x;
#endif
{

View File

@ -33,9 +33,9 @@ static double huge = 1.0e300;
#endif
#ifdef __STDC__
double ceil(double x)
double __generic_ceil(double x)
#else
double ceil(x)
double __generic_ceil(x)
double x;
#endif
{

View File

@ -24,9 +24,9 @@ static char rcsid[] = "$FreeBSD$";
#include "math_private.h"
#ifdef __STDC__
double copysign(double x, double y)
double __generic_copysign(double x, double y)
#else
double copysign(x,y)
double __generic_copysign(x,y)
double x,y;
#endif
{

View File

@ -49,9 +49,9 @@ static char rcsid[] = "$FreeBSD$";
#include "math_private.h"
#ifdef __STDC__
double cos(double x)
double __generic_cos(double x)
#else
double cos(x)
double __generic_cos(x)
double x;
#endif
{

View File

@ -23,9 +23,9 @@ static char rcsid[] = "$FreeBSD$";
#include "math_private.h"
#ifdef __STDC__
int finite(double x)
int __generic_finite(double x)
#else
int finite(x)
int __generic_finite(x)
double x;
#endif
{

View File

@ -33,9 +33,9 @@ static double huge = 1.0e300;
#endif
#ifdef __STDC__
double floor(double x)
double __generic_floor(double x)
#else
double floor(x)
double __generic_floor(x)
double x;
#endif
{

View File

@ -24,9 +24,9 @@ static char rcsid[] = "$FreeBSD$";
#include "math_private.h"
#ifdef __STDC__
int ilogb(double x)
int __generic_ilogb(double x)
#else
int ilogb(x)
int __generic_ilogb(x)
double x;
#endif
{

View File

@ -24,9 +24,9 @@ static char rcsid[] = "$FreeBSD$";
#include "math_private.h"
#ifdef __STDC__
double logb(double x)
double __generic_logb(double x)
#else
double logb(x)
double __generic_logb(x)
double x;
#endif
{

View File

@ -45,9 +45,9 @@ TWO52[2]={
};
#ifdef __STDC__
double rint(double x)
double __generic_rint(double x)
#else
double rint(x)
double __generic_rint(x)
double x;
#endif
{

View File

@ -35,9 +35,9 @@ huge = 1.0e+300,
tiny = 1.0e-300;
#ifdef __STDC__
double scalbn (double x, int n)
double __generic_scalbn (double x, int n)
#else
double scalbn (x,n)
double __generic_scalbn (x,n)
double x; int n;
#endif
{

View File

@ -24,9 +24,9 @@ static char rcsid[] = "$FreeBSD$";
#include "math_private.h"
#ifdef __STDC__
double significand(double x)
double __generic_significand(double x)
#else
double significand(x)
double __generic_significand(x)
double x;
#endif
{

View File

@ -49,9 +49,9 @@ static char rcsid[] = "$FreeBSD$";
#include "math_private.h"
#ifdef __STDC__
double sin(double x)
double __generic_sin(double x)
#else
double sin(x)
double __generic_sin(x)
double x;
#endif
{

View File

@ -48,9 +48,9 @@ static char rcsid[] = "$FreeBSD$";
#include "math_private.h"
#ifdef __STDC__
double tan(double x)
double __generic_tan(double x)
#else
double tan(x)
double __generic_tan(x)
double x;
#endif
{

View File

@ -31,12 +31,6 @@
#WANT_CSRG_LIBM= yes
#
#
# If you have a FPU (i387, i486DX, Pentium), you can make
# the Sun libm use the FPU:
#
#HAVE_FPU= yes
#
#
# If you do not want unformatted manual pages to be compressed
# when they are installed:
#

View File

@ -127,6 +127,83 @@
#include "/usr/src/lib/libc/i386/DEFS.h" /* XXX blech */
/*
* In the !KERNEL case, this header is only (ab)used in lib/msun/i387.
* Use it to generate code to select between the generic math functions
* and the i387 ones.
*/
#undef ENTRY
#define ANAME(x) CNAME(__CONCAT(__i387_,x))
#define ASELNAME(x) CNAME(__CONCAT(__arch_select_,x))
#define AVECNAME(x) CNAME(__CONCAT(__arch_,x))
#define GNAME(x) CNAME(__CONCAT(__generic_,x))
/* Don't bother profiling this. */
#ifdef PIC
#define ARCH_DISPATCH(x) \
START_ENTRY; \
.globl CNAME(x); .type CNAME(x),@function; CNAME(x): ; \
PIC_PROLOGUE; \
movl PIC_GOT(AVECNAME(x)),%eax; \
PIC_EPILOGUE; \
jmpl *(%eax)
#define ARCH_SELECT(x) START_ENTRY; \
.type ASELNAME(x),@function; \
ASELNAME(x): \
PIC_PROLOGUE; \
call PIC_PLT(CNAME(__get_hw_float)); \
testl %eax,%eax; \
movl PIC_GOT(ANAME(x)),%eax; \
jne 8f; \
movl PIC_GOT(GNAME(x)),%eax; \
8: \
movl PIC_GOT(AVECNAME(x)),%edx; \
movl %eax,(%edx); \
PIC_EPILOGUE; \
jmpl *%eax
#else /* !PIC */
#define ARCH_DISPATCH(x) \
START_ENTRY; \
.globl CNAME(x); .type CNAME(x),@function; CNAME(x): ; \
jmpl *AVECNAME(x)
#define ARCH_SELECT(x) START_ENTRY; \
.type ASELNAME(x),@function; \
ASELNAME(x): \
call CNAME(__get_hw_float); \
testl %eax,%eax; \
movl $ANAME(x),%eax; \
jne 8f; \
movl $GNAME(x),%eax; \
8: \
movl %eax,AVECNAME(x); \
jmpl *%eax
#endif /* PIC */
#define ARCH_VECTOR(x) .data; .align 2; \
.globl AVECNAME(x); \
.type AVECNAME(x),@object; \
.size AVECNAME(x),4; \
AVECNAME(x): .long ASELNAME(x)
#ifdef PROF
#define ALTENTRY(x) ENTRY(x); jmp 9f
#define ENTRY(x) ARCH_VECTOR(x); ARCH_SELECT(x); ARCH_DISPATCH(x); \
START_ENTRY; \
.globl ANAME(x); .type ANAME(x),@function; ANAME(x):; \
call HIDENAME(mcount); 9:
#else /* !PROF */
#define ALTENTRY(x) ENTRY(x)
#define ENTRY(x) ARCH_VECTOR(x); ARCH_SELECT(x); ARCH_DISPATCH(x); \
START_ENTRY; \
.globl ANAME(x); .type ANAME(x),@function; ANAME(x):
#endif /* PROF */
#ifndef RCSID
#define RCSID(a)
#endif

View File

@ -127,6 +127,83 @@
#include "/usr/src/lib/libc/i386/DEFS.h" /* XXX blech */
/*
* In the !KERNEL case, this header is only (ab)used in lib/msun/i387.
* Use it to generate code to select between the generic math functions
* and the i387 ones.
*/
#undef ENTRY
#define ANAME(x) CNAME(__CONCAT(__i387_,x))
#define ASELNAME(x) CNAME(__CONCAT(__arch_select_,x))
#define AVECNAME(x) CNAME(__CONCAT(__arch_,x))
#define GNAME(x) CNAME(__CONCAT(__generic_,x))
/* Don't bother profiling this. */
#ifdef PIC
#define ARCH_DISPATCH(x) \
START_ENTRY; \
.globl CNAME(x); .type CNAME(x),@function; CNAME(x): ; \
PIC_PROLOGUE; \
movl PIC_GOT(AVECNAME(x)),%eax; \
PIC_EPILOGUE; \
jmpl *(%eax)
#define ARCH_SELECT(x) START_ENTRY; \
.type ASELNAME(x),@function; \
ASELNAME(x): \
PIC_PROLOGUE; \
call PIC_PLT(CNAME(__get_hw_float)); \
testl %eax,%eax; \
movl PIC_GOT(ANAME(x)),%eax; \
jne 8f; \
movl PIC_GOT(GNAME(x)),%eax; \
8: \
movl PIC_GOT(AVECNAME(x)),%edx; \
movl %eax,(%edx); \
PIC_EPILOGUE; \
jmpl *%eax
#else /* !PIC */
#define ARCH_DISPATCH(x) \
START_ENTRY; \
.globl CNAME(x); .type CNAME(x),@function; CNAME(x): ; \
jmpl *AVECNAME(x)
#define ARCH_SELECT(x) START_ENTRY; \
.type ASELNAME(x),@function; \
ASELNAME(x): \
call CNAME(__get_hw_float); \
testl %eax,%eax; \
movl $ANAME(x),%eax; \
jne 8f; \
movl $GNAME(x),%eax; \
8: \
movl %eax,AVECNAME(x); \
jmpl *%eax
#endif /* PIC */
#define ARCH_VECTOR(x) .data; .align 2; \
.globl AVECNAME(x); \
.type AVECNAME(x),@object; \
.size AVECNAME(x),4; \
AVECNAME(x): .long ASELNAME(x)
#ifdef PROF
#define ALTENTRY(x) ENTRY(x); jmp 9f
#define ENTRY(x) ARCH_VECTOR(x); ARCH_SELECT(x); ARCH_DISPATCH(x); \
START_ENTRY; \
.globl ANAME(x); .type ANAME(x),@function; ANAME(x):; \
call HIDENAME(mcount); 9:
#else /* !PROF */
#define ALTENTRY(x) ENTRY(x)
#define ENTRY(x) ARCH_VECTOR(x); ARCH_SELECT(x); ARCH_DISPATCH(x); \
START_ENTRY; \
.globl ANAME(x); .type ANAME(x),@function; ANAME(x):
#endif /* PROF */
#ifndef RCSID
#define RCSID(a)
#endif