From adb103acec06f5f4e58c22a3b050d09429c216eb Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 25 May 2012 21:25:13 -0400 Subject: [PATCH] Build fixes for Windows --- Make.inc | 18 ++- Makefile | 2 +- amd64/bsd_ieeefp.h | 283 +++++++++++++++++++++++++++++++++++++++++ i387/Make.files | 18 ++- i387/bsd_asm.h | 21 +-- i387/bsd_ieeefp.h | 2 + i387/bsd_npx.h | 160 +++++++++++++++++++++++ i387/fenv.c | 26 ++-- i387/fenv.h | 40 +++--- include/cdefs-compat.h | 3 +- ld80/Make.files | 6 +- ld80/s_exp2l.c | 7 +- src/Make.files | 6 +- src/s_cbrtl.c | 3 + 14 files changed, 531 insertions(+), 64 deletions(-) create mode 100644 amd64/bsd_ieeefp.h create mode 100644 i387/bsd_ieeefp.h create mode 100644 i387/bsd_npx.h diff --git a/Make.inc b/Make.inc index 87ab640..f8d0986 100644 --- a/Make.inc +++ b/Make.inc @@ -1,5 +1,7 @@ CC=gcc -CFLAGS= -Wall -O2 -I$(OPENLIBM_HOME) -I$(OPENLIBM_HOME)/include -I$(OPENLIBM_HOME)/ld80 -I$(OPENLIBM_HOME)/src -DASSEMBLER -D__BSD_VISIBLE -Wno-implicit-function-declaration +OS = $(shell uname) +ARCH = $(shell uname -m) +CFLAGS= -std=gnu99 -Wall -O2 -I$(OPENLIBM_HOME) -I$(OPENLIBM_HOME)/include -I$(OPENLIBM_HOME)/ld80 -I$(OPENLIBM_HOME)/$(ARCH) -I$(OPENLIBM_HOME)/src -DASSEMBLER -D__BSD_VISIBLE -Wno-implicit-function-declaration default: all @@ -13,9 +15,6 @@ clean: rm -f *.o *.c.o *.S.o *~ # OS-specific stuff -OS = $(shell uname) -ARCH = $(shell uname -m) - ifeq ($(ARCH),i386) override ARCH = i387 endif @@ -24,23 +23,28 @@ ifeq ($(ARCH),x86_64) override ARCH = amd64 endif +ifeq ($(ARCH),i686) +override ARCH = amd64 +endif + ifeq ($(OS), MINGW32_NT-6.1) OS=WINNT +CFLAGS+=-nodefaultlibs endif ifeq ($(OS), Linux) SHLIB_EXT = so -CFLAGS+=-std=gnu99 -fPIC +CFLAGS+=-fPIC endif ifeq ($(OS), FreeBSD) SHLIB_EXT = so -CFLAGS+=-std=gnu99 -fPIC +CFLAGS+=-fPIC endif ifeq ($(OS), Darwin) SHLIB_EXT = dylib -CFLAGS+=-std=gnu99 -fPIC +CFLAGS+=-fPIC endif ifeq ($(OS), WINNT) diff --git a/Makefile b/Makefile index ee7a75e..d1b3c1a 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ all: libopenlibm.a libopenlibm.$(SHLIB_EXT) libopenlibm.a: $(OBJS) $(QUIET_LINK)ar -rcs libopenlibm.a $(OBJS) libopenlibm.$(SHLIB_EXT): $(OBJS) - $(QUIET_LINK)$(CC) -shared -fPIC $(OBJS) -o libopenlibm.$(SHLIB_EXT) + $(QUIET_LINK)$(CC) -shared $(OBJS) -o libopenlibm.$(SHLIB_EXT) cleanall: rm -f $(OBJS) *.a *.$(SHLIB_EXT) diff --git a/amd64/bsd_ieeefp.h b/amd64/bsd_ieeefp.h new file mode 100644 index 0000000..7fe3b15 --- /dev/null +++ b/amd64/bsd_ieeefp.h @@ -0,0 +1,283 @@ +/*- + * Copyright (c) 2003 Peter Wemm. + * Copyright (c) 1990 Andrew Moore, Talke Studio + * 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 the University of + * California, Berkeley and its contributors. + * 4. 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: @(#) ieeefp.h 1.0 (Berkeley) 9/23/93 + * $FreeBSD: src/sys/amd64/include/ieeefp.h,v 1.14 2005/04/12 23:12:00 jhb Exp $ + */ + +/* + * IEEE floating point type and constant definitions. + */ + +#ifndef _MACHINE_IEEEFP_H_ +#define _MACHINE_IEEEFP_H_ +#warning test + +#ifndef _SYS_CDEFS_H_ +#error this file needs sys/cdefs.h as a prerequisite +#endif + +/* + * FP rounding modes + */ +typedef enum { + FP_RN=0, /* round to nearest */ + FP_RM, /* round down to minus infinity */ + FP_RP, /* round up to plus infinity */ + FP_RZ /* truncate */ +} fp_rnd_t; + +/* + * FP precision modes + */ +typedef enum { + FP_PS=0, /* 24 bit (single-precision) */ + FP_PRS, /* reserved */ + FP_PD, /* 53 bit (double-precision) */ + FP_PE /* 64 bit (extended-precision) */ +} fp_prec_t; + +#define fp_except_t int + +/* + * FP exception masks + */ +#define FP_X_INV 0x01 /* invalid operation */ +#define FP_X_DNML 0x02 /* denormal */ +#define FP_X_DZ 0x04 /* zero divide */ +#define FP_X_OFL 0x08 /* overflow */ +#define FP_X_UFL 0x10 /* underflow */ +#define FP_X_IMP 0x20 /* (im)precision */ +#define FP_X_STK 0x40 /* stack fault */ + +/* + * FP registers + */ +#define FP_MSKS_REG 0 /* exception masks */ +#define FP_PRC_REG 0 /* precision */ +#define FP_RND_REG 0 /* direction */ +#define FP_STKY_REG 1 /* sticky flags */ + +/* + * FP register bit field masks + */ +#define FP_MSKS_FLD 0x3f /* exception masks field */ +#define FP_PRC_FLD 0x300 /* precision control field */ +#define FP_RND_FLD 0xc00 /* round control field */ +#define FP_STKY_FLD 0x3f /* sticky flags field */ + +/* + * SSE mxcsr register bit field masks + */ +#define SSE_STKY_FLD 0x3f /* exception flags */ +#define SSE_DAZ_FLD 0x40 /* Denormals are zero */ +#define SSE_MSKS_FLD 0x1f80 /* exception masks field */ +#define SSE_RND_FLD 0x6000 /* rounding control */ +#define SSE_FZ_FLD 0x8000 /* flush to zero on underflow */ + +/* + * FP register bit field offsets + */ +#define FP_MSKS_OFF 0 /* exception masks offset */ +#define FP_PRC_OFF 8 /* precision control offset */ +#define FP_RND_OFF 10 /* round control offset */ +#define FP_STKY_OFF 0 /* sticky flags offset */ + +/* + * SSE mxcsr register bit field offsets + */ +#define SSE_STKY_OFF 0 /* exception flags offset */ +#define SSE_DAZ_OFF 6 /* DAZ exception mask offset */ +#define SSE_MSKS_OFF 7 /* other exception masks offset */ +#define SSE_RND_OFF 13 /* rounding control offset */ +#define SSE_FZ_OFF 15 /* flush to zero offset */ + +#if (defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE__)) || defined(__WIN32__) \ + && !defined(__cplusplus) + +#warning test2 + +#define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) +#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) +#define __fldcw(addr) __asm __volatile("fldcw %0" : : "m" (*(addr))) +#define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) +#define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) +#define __ldmxcsr(addr) __asm __volatile("ldmxcsr %0" : : "m" (*(addr))) +#define __stmxcsr(addr) __asm __volatile("stmxcsr %0" : "=m" (*(addr))) + +/* + * General notes about conflicting SSE vs FP status bits. + * This code assumes that software will not fiddle with the control + * bits of the SSE and x87 in such a way to get them out of sync and + * still expect this to work. Break this at your peril. + * Because I based this on the i386 port, the x87 state is used for + * the fpget*() functions, and is shadowed into the SSE state for + * the fpset*() functions. For dual source fpget*() functions, I + * merge the two together. I think. + */ + +/* Set rounding control */ +static __inline__ fp_rnd_t +__fpgetround(void) +{ + unsigned short _cw; + + __fnstcw(&_cw); + return ((_cw & FP_RND_FLD) >> FP_RND_OFF); +} + +static __inline__ fp_rnd_t +__fpsetround(fp_rnd_t _m) +{ + unsigned short _cw; + unsigned int _mxcsr; + fp_rnd_t _p; + + __fnstcw(&_cw); + _p = (_cw & FP_RND_FLD) >> FP_RND_OFF; + _cw &= ~FP_RND_FLD; + _cw |= (_m << FP_RND_OFF) & FP_RND_FLD; + __fldcw(&_cw); + __stmxcsr(&_mxcsr); + _mxcsr &= ~SSE_RND_FLD; + _mxcsr |= (_m << SSE_RND_OFF) & SSE_RND_FLD; + __ldmxcsr(&_mxcsr); + return (_p); +} + +/* + * Set precision for fadd/fsub/fsqrt etc x87 instructions + * There is no equivalent SSE mode or control. + */ +static __inline__ fp_prec_t +__fpgetprec(void) +{ + unsigned short _cw; + + __fnstcw(&_cw); + return ((_cw & FP_PRC_FLD) >> FP_PRC_OFF); +} + +static __inline__ fp_prec_t +__fpsetprec(fp_rnd_t _m) +{ + unsigned short _cw; + fp_prec_t _p; + + __fnstcw(&_cw); + _p = (_cw & FP_PRC_FLD) >> FP_PRC_OFF; + _cw &= ~FP_PRC_FLD; + _cw |= (_m << FP_PRC_OFF) & FP_PRC_FLD; + __fldcw(&_cw); + return (_p); +} + +/* + * Look at the exception masks + * Note that x87 masks are inverse of the fp*() functions + * API. ie: mask = 1 means disable for x87 and SSE, but + * for the fp*() api, mask = 1 means enabled. + */ +static __inline__ fp_except_t +__fpgetmask(void) +{ + unsigned short _cw; + + __fnstcw(&_cw); + return ((~_cw) & FP_MSKS_FLD); +} + +static __inline__ fp_except_t +__fpsetmask(fp_except_t _m) +{ + unsigned short _cw; + unsigned int _mxcsr; + fp_except_t _p; + + __fnstcw(&_cw); + _p = (~_cw) & FP_MSKS_FLD; + _cw &= ~FP_MSKS_FLD; + _cw |= (~_m) & FP_MSKS_FLD; + __fldcw(&_cw); + __stmxcsr(&_mxcsr); + /* XXX should we clear non-ieee SSE_DAZ_FLD and SSE_FZ_FLD ? */ + _mxcsr &= ~SSE_MSKS_FLD; + _mxcsr |= ((~_m) << SSE_MSKS_OFF) & SSE_MSKS_FLD; + __ldmxcsr(&_mxcsr); + return (_p); +} + +/* See which sticky exceptions are pending, and reset them */ +static __inline__ fp_except_t +__fpgetsticky(void) +{ + unsigned short _sw; + unsigned int _mxcsr; + fp_except_t _ex; + + __fnstsw(&_sw); + _ex = _sw & FP_STKY_FLD; + __stmxcsr(&_mxcsr); + _ex |= _mxcsr & SSE_STKY_FLD; + return (_ex); +} + +#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE__ && !__cplusplus */ + +#if !defined(__IEEEFP_NOINLINES__) && !defined(__cplusplus) \ + && defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE__) + +#define fpgetround() __fpgetround() +#define fpsetround(_m) __fpsetround(_m) +#define fpgetprec() __fpgetprec() +#define fpsetprec(_m) __fpsetprec(_m) +#define fpgetmask() __fpgetmask() +#define fpsetmask(_m) __fpsetmask(_m) +#define fpgetsticky() __fpgetsticky() + +/* Suppress prototypes in the MI header. */ +#define _IEEEFP_INLINED_ 1 + +#else /* !__IEEEFP_NOINLINES__ && !__cplusplus && __GNUCLIKE_ASM + && __CC_SUPPORTS___INLINE__ */ + +/* Augment the userland declarations */ +__BEGIN_DECLS +extern fp_prec_t fpgetprec(void); +extern fp_prec_t fpsetprec(fp_prec_t); +__END_DECLS + +#endif /* !__IEEEFP_NOINLINES__ && !__cplusplus && __GNUCLIKE_ASM + && __CC_SUPPORTS___INLINE__ */ + +#endif /* !_MACHINE_IEEEFP_H_ */ \ No newline at end of file diff --git a/i387/Make.files b/i387/Make.files index 0f34802..7e765ad 100644 --- a/i387/Make.files +++ b/i387/Make.files @@ -1,16 +1,22 @@ -ARCH_SRCS = e_exp.S e_fmod.S e_log.S e_log10.S \ +$(CUR_SRCS) = e_exp.S e_fmod.S e_log.S e_log10.S \ e_remainder.S e_sqrt.S s_ceil.S s_copysign.S \ s_cos.S s_finite.S s_floor.S s_llrint.S s_logb.S s_lrint.S \ - s_remquo.S s_rint.S s_scalbn.S s_significand.S s_sin.S s_tan.S \ + s_remquo.S s_rint.S s_significand.S s_sin.S s_tan.S \ s_trunc.S +ifneq ($(OS), WINNT) +$(CUR_SRCS) += s_scalbn.S s_scalbnf.S s_scalbnl.S +endif + # float counterparts -ARCH_SRCS+= e_log10f.S e_logf.S e_remainderf.S \ +$(CUR_SRCS)+= e_log10f.S e_logf.S e_remainderf.S \ e_sqrtf.S s_ceilf.S s_copysignf.S s_floorf.S \ s_llrintf.S s_logbf.S s_lrintf.S \ - s_remquof.S s_rintf.S s_scalbnf.S s_significandf.S s_truncf.S + s_remquof.S s_rintf.S s_significandf.S s_truncf.S # long double counterparts -ARCH_SRCS+= e_remainderl.S e_sqrtl.S s_ceill.S s_copysignl.S \ +$(CUR_SRCS)+= e_remainderl.S e_sqrtl.S s_ceill.S s_copysignl.S \ s_floorl.S s_llrintl.S \ - s_logbl.S s_lrintl.S s_remquol.S s_rintl.S s_scalbnl.S s_truncl.S + s_logbl.S s_lrintl.S s_remquol.S s_rintl.S s_truncl.S + +$(CUR_SRCS)+= fenv.c \ No newline at end of file diff --git a/i387/bsd_asm.h b/i387/bsd_asm.h index 2e8b350..ead1bd6 100644 --- a/i387/bsd_asm.h +++ b/i387/bsd_asm.h @@ -39,7 +39,7 @@ #if defined(__APPLE__) #include "osx_asm.h" #define CNAME(x) EXT(x) -#elif defined(__FreeBSD__) || defined(__linux__) +#elif defined(__FreeBSD__) || defined(__linux__) || defined(__WIN32__) #include "bsd_cdefs.h" #ifdef PIC @@ -68,30 +68,23 @@ * to a possibly-modified form that will be invisible to C programs. */ -#if defined(__FreeBSD__) || defined(__linux__) #define CNAME(csym) csym #define HIDENAME(asmsym) .asmsym /* XXX should use .p2align 4,0x90 for -m486. */ #define _START_ENTRY .text; .p2align 2,0x90 +#if defined(__linux__) || defined(__FreeBSD__) || defined(__ELF__) #define _ENTRY(x) _START_ENTRY; \ .globl CNAME(x); .type CNAME(x),@function; CNAME(x): #define END(x) .size x, . - x -#else -#define CNAME(csym) _csym -#define HIDENAME(asmsym) .asmsym - -/* XXX should use .p2align 4,0x90 for -m486. */ -#define _START_ENTRY .text; .p2align 2,0x90 - -#define _ENTRY(x) _START_ENTRY; \ - .globl CNAME(x); CNAME(x): -#define END(x) .size x, . - x +#elif defined(__WIN32__) +#define _ENTRY(x) \ + _START_ENTRY; .globl CNAME(x) ; .def CNAME(X);\ + .scl 2;.type 32;.endef; CNAME(x): +#define END(x) .end #endif - - #ifdef PROF #define ALTENTRY(x) _ENTRY(x); \ pushl %ebp; movl %esp,%ebp; \ diff --git a/i387/bsd_ieeefp.h b/i387/bsd_ieeefp.h new file mode 100644 index 0000000..088065e --- /dev/null +++ b/i387/bsd_ieeefp.h @@ -0,0 +1,2 @@ +#include "include/cdefs-compat.h" +#include "amd64/bsd_ieeefp.h" \ No newline at end of file diff --git a/i387/bsd_npx.h b/i387/bsd_npx.h new file mode 100644 index 0000000..78c5cbe --- /dev/null +++ b/i387/bsd_npx.h @@ -0,0 +1,160 @@ +/*- + * 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. + * 4. 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: @(#)npx.h 5.3 (Berkeley) 1/18/91 + * $FreeBSD: src/sys/i386/include/npx.h,v 1.29.2.1 2006/07/01 00:57:55 davidxu Exp $ + */ + +/* + * 287/387 NPX Coprocessor Data Structures and Constants + * W. Jolitz 1/90 + */ + +#ifndef _MACHINE_NPX_H_ +#define _MACHINE_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 */ + unsigned short en_fcs; /* floating code segment selector */ + unsigned short 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 */ + unsigned long fp_mantlo; /* mantissa low (31:0) */ + unsigned long fp_manthi; /* mantissa high (63:32) */ + int fp_exp:15; /* exponent */ + int fp_sgn:1; /* mantissa sign */ +#else + unsigned char 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 */ + unsigned char sv_pad0[4]; /* padding for (now unused) saved status word */ + /* + * Bogus padding for emulators. Emulators should use their own + * struct and arrange to store into this struct (ending here) + * before it is inspected for ptracing or for core dumps. Some + * emulators overwrite the whole struct. We have no good way of + * knowing how much padding to leave. Leave just enough for the + * GPL emulator's i387_union (176 bytes total). + */ + unsigned char sv_pad[64]; /* padding; used by emulators */ +}; + +struct envxmm { + uint16_t en_cw; /* control word (16bits) */ + uint16_t en_sw; /* status word (16bits) */ + uint16_t en_tw; /* tag word (16bits) */ + uint16_t en_opcode; /* opcode last executed (11 bits ) */ + uint32_t en_fip; /* floating point instruction pointer */ + uint16_t en_fcs; /* floating code segment selector */ + uint16_t en_pad0; /* padding */ + uint32_t en_foo; /* floating operand offset */ + uint16_t en_fos; /* floating operand segment selector */ + uint16_t en_pad1; /* padding */ + uint32_t en_mxcsr; /* SSE sontorol/status register */ + uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ +}; + +/* Contents of each SSE extended accumulator */ +struct xmmacc { + unsigned char xmm_bytes[16]; +}; + +struct savexmm { + struct envxmm sv_env; + struct { + struct fpacc87 fp_acc; + unsigned char fp_pad[6]; /* padding */ + } sv_fp[8]; + struct xmmacc sv_xmm[8]; + unsigned char sv_pad[224]; +} __attribute__((__aligned__(16))); + +union savefpu { + struct save87 sv_87; + struct savexmm sv_xmm; +}; + +/* + * The hardware default control word for i387's and later coprocessors is + * 0x37F, giving: + * + * round to nearest + * 64-bit precision + * all exceptions masked. + * + * We modify the affine mode bit and precision bits in this to give: + * + * affine mode for 287's (if they work at all) (1 in bitfield 1<<12) + * 53-bit precision (2 in bitfield 3<<8) + * + * 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. + */ +#define __INITIAL_NPXCW__ 0x127F +#define __INITIAL_MXCSR__ 0x1F80 + +#ifdef _KERNEL + +#define IO_NPX 0x0F0 /* Numeric Coprocessor */ +#define IO_NPXSIZE 16 /* 80387/80487 NPX registers */ + +#define IRQ_NPX 13 + +/* full reset on some systems, NOP on others */ +#define npx_full_reset() outb(IO_NPX + 1, 0) + +int npxdna(void); +void npxdrop(void); +void npxexit(struct thread *td); +int npxformat(void); +int npxgetregs(struct thread *td, union savefpu *addr); +void npxinit(unsigned short control); +void npxsave(union savefpu *addr); +void npxsetregs(struct thread *td, union savefpu *addr); +int npxtrap(void); +#endif + +#endif /* !_MACHINE_NPX_H_ */ \ No newline at end of file diff --git a/i387/fenv.c b/i387/fenv.c index 2c4c034..4c13c19 100644 --- a/i387/fenv.c +++ b/i387/fenv.c @@ -26,9 +26,13 @@ * $FreeBSD: src/lib/msun/i387/fenv.c,v 1.8 2011/10/21 06:25:31 das Exp $ */ -#include -#include +#include +#include +#ifdef __WIN32__ +#include +#else #include +#endif #define __fenv_static #include "fenv.h" @@ -96,7 +100,7 @@ int fesetexceptflag(const fexcept_t *flagp, int excepts) { fenv_t env; - __uint32_t mxcsr; + uint32_t mxcsr; __fnstenv(&env); env.__status &= ~excepts; @@ -130,7 +134,7 @@ extern inline int fesetround(int __round); int fegetenv(fenv_t *envp) { - __uint32_t mxcsr; + uint32_t mxcsr; __fnstenv(envp); /* @@ -148,7 +152,7 @@ fegetenv(fenv_t *envp) int feholdexcept(fenv_t *envp) { - __uint32_t mxcsr; + uint32_t mxcsr; __fnstenv(envp); __fnclex(); @@ -167,8 +171,8 @@ extern inline int fesetenv(const fenv_t *__envp); int feupdateenv(const fenv_t *envp) { - __uint32_t mxcsr; - __uint16_t status; + uint32_t mxcsr; + uint16_t status; __fnstsw(&status); if (__HAS_SSE()) @@ -183,8 +187,8 @@ feupdateenv(const fenv_t *envp) int __feenableexcept(int mask) { - __uint32_t mxcsr, omask; - __uint16_t control; + uint32_t mxcsr, omask; + uint16_t control; mask &= FE_ALL_EXCEPT; __fnstcw(&control); @@ -205,8 +209,8 @@ __feenableexcept(int mask) int __fedisableexcept(int mask) { - __uint32_t mxcsr, omask; - __uint16_t control; + uint32_t mxcsr, omask; + uint16_t control; mask &= FE_ALL_EXCEPT; __fnstcw(&control); diff --git a/i387/fenv.h b/i387/fenv.h index ed2c57e..0dc51ae 100644 --- a/i387/fenv.h +++ b/i387/fenv.h @@ -29,8 +29,8 @@ #ifndef _FENV_H_ #define _FENV_H_ -#include -#include +#include "include/cdefs-compat.h" +#include "include/types-compat.h" #ifndef __fenv_static #define __fenv_static static @@ -41,22 +41,22 @@ * mxcsr into some reserved fields, rather than changing sizeof(fenv_t). */ typedef struct { - __uint16_t __control; - __uint16_t __mxcsr_hi; - __uint16_t __status; - __uint16_t __mxcsr_lo; - __uint32_t __tag; + uint16_t __control; + uint16_t __mxcsr_hi; + uint16_t __status; + uint16_t __mxcsr_lo; + uint32_t __tag; char __other[16]; } fenv_t; #define __get_mxcsr(env) (((env).__mxcsr_hi << 16) | \ ((env).__mxcsr_lo)) #define __set_mxcsr(env, x) do { \ - (env).__mxcsr_hi = (__uint32_t)(x) >> 16; \ - (env).__mxcsr_lo = (__uint16_t)(x); \ + (env).__mxcsr_hi = (uint32_t)(x) >> 16; \ + (env).__mxcsr_lo = (uint16_t)(x); \ } while (0) -typedef __uint16_t fexcept_t; +typedef uint16_t fexcept_t; /* Exception flags */ #define FE_INVALID 0x01 @@ -118,7 +118,7 @@ __fenv_static inline int feclearexcept(int __excepts) { fenv_t __env; - __uint32_t __mxcsr; + uint32_t __mxcsr; if (__excepts == FE_ALL_EXCEPT) { __fnclex(); @@ -138,8 +138,8 @@ feclearexcept(int __excepts) __fenv_static inline int fegetexceptflag(fexcept_t *__flagp, int __excepts) { - __uint32_t __mxcsr; - __uint16_t __status; + uint32_t __mxcsr; + uint16_t __status; __fnstsw(&__status); if (__HAS_SSE()) @@ -156,8 +156,8 @@ int feraiseexcept(int __excepts); __fenv_static inline int fetestexcept(int __excepts) { - __uint32_t __mxcsr; - __uint16_t __status; + uint32_t __mxcsr; + uint16_t __status; __fnstsw(&__status); if (__HAS_SSE()) @@ -170,7 +170,7 @@ fetestexcept(int __excepts) __fenv_static inline int fegetround(void) { - __uint16_t __control; + uint16_t __control; /* * We assume that the x87 and the SSE unit agree on the @@ -185,8 +185,8 @@ fegetround(void) __fenv_static inline int fesetround(int __round) { - __uint32_t __mxcsr; - __uint16_t __control; + uint32_t __mxcsr; + uint16_t __control; if (__round & ~_ROUND_MASK) return (-1); @@ -213,7 +213,7 @@ __fenv_static inline int fesetenv(const fenv_t *__envp) { fenv_t __env = *__envp; - __uint32_t __mxcsr; + uint32_t __mxcsr; __mxcsr = __get_mxcsr(__env); __set_mxcsr(__env, 0xffffffff); @@ -242,7 +242,7 @@ int fedisableexcept(int __mask); static inline int fegetexcept(void) { - __uint16_t __control; + uint16_t __control; /* * We assume that the masks for the x87 and the SSE unit are diff --git a/include/cdefs-compat.h b/include/cdefs-compat.h index 3631047..be310a1 100644 --- a/include/cdefs-compat.h +++ b/include/cdefs-compat.h @@ -7,7 +7,6 @@ #ifndef __WIN32__ #include "sys/cdefs.h" - #else /* __WIN32__ */ #if defined(__cplusplus) @@ -18,6 +17,8 @@ #define __END_DECLS #endif +#define _SYS_CDEFS_H_ + #endif /* __WIN32__ */ diff --git a/ld80/Make.files b/ld80/Make.files index 1d8bb94..f4f9a76 100644 --- a/ld80/Make.files +++ b/ld80/Make.files @@ -1,2 +1,6 @@ $(CUR_SRCS) += invtrig.c k_cosl.c k_sinl.c\ - k_tanl.c s_exp2l.c s_nanl.c + k_tanl.c s_exp2l.c + +ifneq ($(OS), WINNT) +$(CUR_SRCS) += s_nanl.c +endif \ No newline at end of file diff --git a/ld80/s_exp2l.c b/ld80/s_exp2l.c index a0393c7..50cd89a 100644 --- a/ld80/s_exp2l.c +++ b/ld80/s_exp2l.c @@ -30,7 +30,9 @@ #include #include -#ifdef __i386__ +#ifdef __WIN32__ +#include "amd64/bsd_ieeefp.h" +#else #include #endif @@ -243,10 +245,11 @@ exp2l(long double x) * The default precision on i386 is 53 bits, so long doubles are * broken. Call exp2() to get an accurate (double precision) result. */ - if (fpgetprec() != FP_PE) + if (__fpgetprec() != FP_PE) return (exp2(x)); #endif + /* * Reduce x, computing z, i0, and k. The low bits of x + redux * contain the 16-bit integer part of the exponent (k) followed by diff --git a/src/Make.files b/src/Make.files index 1eee3f8..bf8d487 100644 --- a/src/Make.files +++ b/src/Make.files @@ -24,7 +24,7 @@ $(CUR_SRCS) = \ s_llrint.c s_llrintf.c s_llround.c s_llroundf.c s_llroundl.c \ s_log1p.c s_log1pf.c s_logb.c s_logbf.c s_lrint.c s_lrintf.c \ s_lround.c s_lroundf.c s_lroundl.c s_modf.c s_modff.c \ - s_nan.c s_nearbyint.c s_nextafter.c s_nextafterf.c \ + s_nearbyint.c s_nextafter.c s_nextafterf.c \ s_nexttowardf.c s_remquo.c s_remquof.c \ s_rint.c s_rintf.c s_round.c s_roundf.c s_roundl.c \ s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \ @@ -32,6 +32,10 @@ $(CUR_SRCS) = \ s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_tgammaf.c s_trunc.c s_truncf.c \ w_cabs.c w_cabsf.c w_drem.c w_dremf.c +ifneq ($(OS), WINNT) +$(CUR_SRCS) += s_nan.c +endif + # C99 long double functions $(CUR_SRCS) += s_copysignl.c s_fabsl.c s_llrintl.c s_lrintl.c s_modfl.c diff --git a/src/s_cbrtl.c b/src/s_cbrtl.c index 9ccd5ac..e7c2d10 100644 --- a/src/s_cbrtl.c +++ b/src/s_cbrtl.c @@ -24,6 +24,9 @@ #include "fpmath.h" #include "openlibm.h" #include "math_private.h" +#if defined(__WIN32__) && defined(__i386__) +#include "i387/bsd_ieeefp.h" +#endif #define BIAS (LDBL_MAX_EXP - 1)