From 9e8f1bd4ec847780eb9aaf168c43f1271f0e37f5 Mon Sep 17 00:00:00 2001 From: bde Date: Sun, 16 Feb 1997 18:26:31 +0000 Subject: [PATCH] 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. --- etc/defaults/make.conf | 6 --- etc/make.conf | 6 --- lib/msun/Makefile | 20 ++++++---- lib/msun/src/e_acos.c | 4 +- lib/msun/src/e_asin.c | 4 +- lib/msun/src/e_atan2.c | 4 +- lib/msun/src/e_exp.c | 4 +- lib/msun/src/e_fmod.c | 4 +- lib/msun/src/e_log.c | 4 +- lib/msun/src/e_log10.c | 4 +- lib/msun/src/e_remainder.c | 4 +- lib/msun/src/e_scalb.c | 8 ++-- lib/msun/src/e_sqrt.c | 4 +- lib/msun/src/get_hw_float.c | 50 +++++++++++++++++++++++ lib/msun/src/s_atan.c | 4 +- lib/msun/src/s_ceil.c | 4 +- lib/msun/src/s_copysign.c | 4 +- lib/msun/src/s_cos.c | 4 +- lib/msun/src/s_finite.c | 4 +- lib/msun/src/s_floor.c | 4 +- lib/msun/src/s_ilogb.c | 4 +- lib/msun/src/s_logb.c | 4 +- lib/msun/src/s_rint.c | 4 +- lib/msun/src/s_scalbn.c | 4 +- lib/msun/src/s_significand.c | 4 +- lib/msun/src/s_sin.c | 4 +- lib/msun/src/s_tan.c | 4 +- share/examples/etc/make.conf | 6 --- sys/amd64/include/asmacros.h | 77 ++++++++++++++++++++++++++++++++++++ sys/i386/include/asmacros.h | 77 ++++++++++++++++++++++++++++++++++++ 30 files changed, 264 insertions(+), 74 deletions(-) create mode 100644 lib/msun/src/get_hw_float.c diff --git a/etc/defaults/make.conf b/etc/defaults/make.conf index 0b49ca1e08de..7fee7a8745f7 100644 --- a/etc/defaults/make.conf +++ b/etc/defaults/make.conf @@ -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: # diff --git a/etc/make.conf b/etc/make.conf index 0b49ca1e08de..7fee7a8745f7 100644 --- a/etc/make.conf +++ b/etc/make.conf @@ -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: # diff --git a/lib/msun/Makefile b/lib/msun/Makefile index d4f6bc400514..8bcf65be4736 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -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 diff --git a/lib/msun/src/e_acos.c b/lib/msun/src/e_acos.c index 844803626a6b..4ed7724de13e 100644 --- a/lib/msun/src/e_acos.c +++ b/lib/msun/src/e_acos.c @@ -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 { diff --git a/lib/msun/src/e_asin.c b/lib/msun/src/e_asin.c index bbba765f4fff..ef2d932fed23 100644 --- a/lib/msun/src/e_asin.c +++ b/lib/msun/src/e_asin.c @@ -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 { diff --git a/lib/msun/src/e_atan2.c b/lib/msun/src/e_atan2.c index 06858b04b8fa..b07d543bfcb2 100644 --- a/lib/msun/src/e_atan2.c +++ b/lib/msun/src/e_atan2.c @@ -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 { diff --git a/lib/msun/src/e_exp.c b/lib/msun/src/e_exp.c index 308c682cd9b6..2fc04c61dbb0 100644 --- a/lib/msun/src/e_exp.c +++ b/lib/msun/src/e_exp.c @@ -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 { diff --git a/lib/msun/src/e_fmod.c b/lib/msun/src/e_fmod.c index 761bd4e066a6..f16863072963 100644 --- a/lib/msun/src/e_fmod.c +++ b/lib/msun/src/e_fmod.c @@ -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 { diff --git a/lib/msun/src/e_log.c b/lib/msun/src/e_log.c index 7a61e5b22ddd..6ebeb910d020 100644 --- a/lib/msun/src/e_log.c +++ b/lib/msun/src/e_log.c @@ -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 { diff --git a/lib/msun/src/e_log10.c b/lib/msun/src/e_log10.c index d4a445eb4035..5c02df8c33fb 100644 --- a/lib/msun/src/e_log10.c +++ b/lib/msun/src/e_log10.c @@ -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 { diff --git a/lib/msun/src/e_remainder.c b/lib/msun/src/e_remainder.c index 8bac83dab4b3..c41d392adc58 100644 --- a/lib/msun/src/e_remainder.c +++ b/lib/msun/src/e_remainder.c @@ -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 { diff --git a/lib/msun/src/e_scalb.c b/lib/msun/src/e_scalb.c index 9f7042f3bced..14f167ee0d54 100644 --- a/lib/msun/src/e_scalb.c +++ b/lib/msun/src/e_scalb.c @@ -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 diff --git a/lib/msun/src/e_sqrt.c b/lib/msun/src/e_sqrt.c index caf3b5e68d11..bea3b200abbd 100644 --- a/lib/msun/src/e_sqrt.c +++ b/lib/msun/src/e_sqrt.c @@ -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 { diff --git a/lib/msun/src/get_hw_float.c b/lib/msun/src/get_hw_float.c new file mode 100644 index 000000000000..6d5f0e0fb453 --- /dev/null +++ b/lib/msun/src/get_hw_float.c @@ -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 +#include + +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); +} diff --git a/lib/msun/src/s_atan.c b/lib/msun/src/s_atan.c index d003d18b3834..029fbc29b6fa 100644 --- a/lib/msun/src/s_atan.c +++ b/lib/msun/src/s_atan.c @@ -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 { diff --git a/lib/msun/src/s_ceil.c b/lib/msun/src/s_ceil.c index d88b81d2418e..2c59c783c88d 100644 --- a/lib/msun/src/s_ceil.c +++ b/lib/msun/src/s_ceil.c @@ -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 { diff --git a/lib/msun/src/s_copysign.c b/lib/msun/src/s_copysign.c index 03da3bed89d1..4f758d229d5a 100644 --- a/lib/msun/src/s_copysign.c +++ b/lib/msun/src/s_copysign.c @@ -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 { diff --git a/lib/msun/src/s_cos.c b/lib/msun/src/s_cos.c index 8511c0ccc29e..707af78c97f8 100644 --- a/lib/msun/src/s_cos.c +++ b/lib/msun/src/s_cos.c @@ -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 { diff --git a/lib/msun/src/s_finite.c b/lib/msun/src/s_finite.c index b85145a2f5a3..88e3298d5d79 100644 --- a/lib/msun/src/s_finite.c +++ b/lib/msun/src/s_finite.c @@ -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 { diff --git a/lib/msun/src/s_floor.c b/lib/msun/src/s_floor.c index 197e8a50a60f..85ace779ede2 100644 --- a/lib/msun/src/s_floor.c +++ b/lib/msun/src/s_floor.c @@ -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 { diff --git a/lib/msun/src/s_ilogb.c b/lib/msun/src/s_ilogb.c index 45e7943e1c4c..d2c82650a88b 100644 --- a/lib/msun/src/s_ilogb.c +++ b/lib/msun/src/s_ilogb.c @@ -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 { diff --git a/lib/msun/src/s_logb.c b/lib/msun/src/s_logb.c index 83b697eadf62..8b724f49594c 100644 --- a/lib/msun/src/s_logb.c +++ b/lib/msun/src/s_logb.c @@ -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 { diff --git a/lib/msun/src/s_rint.c b/lib/msun/src/s_rint.c index 44e9353bdefe..aa4145209528 100644 --- a/lib/msun/src/s_rint.c +++ b/lib/msun/src/s_rint.c @@ -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 { diff --git a/lib/msun/src/s_scalbn.c b/lib/msun/src/s_scalbn.c index c881c7f93358..b69bdcd58cdb 100644 --- a/lib/msun/src/s_scalbn.c +++ b/lib/msun/src/s_scalbn.c @@ -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 { diff --git a/lib/msun/src/s_significand.c b/lib/msun/src/s_significand.c index eead5ea1e79d..64d4623e857f 100644 --- a/lib/msun/src/s_significand.c +++ b/lib/msun/src/s_significand.c @@ -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 { diff --git a/lib/msun/src/s_sin.c b/lib/msun/src/s_sin.c index f145b0267f8a..e6b099edb527 100644 --- a/lib/msun/src/s_sin.c +++ b/lib/msun/src/s_sin.c @@ -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 { diff --git a/lib/msun/src/s_tan.c b/lib/msun/src/s_tan.c index 0bd5ed96ee1b..e02584e3116f 100644 --- a/lib/msun/src/s_tan.c +++ b/lib/msun/src/s_tan.c @@ -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 { diff --git a/share/examples/etc/make.conf b/share/examples/etc/make.conf index 0b49ca1e08de..7fee7a8745f7 100644 --- a/share/examples/etc/make.conf +++ b/share/examples/etc/make.conf @@ -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: # diff --git a/sys/amd64/include/asmacros.h b/sys/amd64/include/asmacros.h index d9188537fea2..3cfedeb1ff8e 100644 --- a/sys/amd64/include/asmacros.h +++ b/sys/amd64/include/asmacros.h @@ -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 diff --git a/sys/i386/include/asmacros.h b/sys/i386/include/asmacros.h index d9188537fea2..3cfedeb1ff8e 100644 --- a/sys/i386/include/asmacros.h +++ b/sys/i386/include/asmacros.h @@ -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