[haiku-commits] r35437 - in haiku/trunk: headers/posix headers/posix/arch/arm headers/posix/arch/ppc headers/posix/arch/x86 src/system/libroot ...

  • From: aljen-mlists@xxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 9 Feb 2010 07:09:28 +0100 (CET)

Author: aljen
Date: 2010-02-09 07:09:28 +0100 (Tue, 09 Feb 2010)
New Revision: 35437
Changeset: http://dev.haiku-os.org/changeset/35437/haiku

Added:
   haiku/trunk/headers/posix/arch/arm/fenv.h
   haiku/trunk/headers/posix/arch/ppc/fenv.h
   haiku/trunk/headers/posix/arch/x86/fenv.h
   haiku/trunk/headers/posix/arch/x86/npx.h
   haiku/trunk/headers/posix/fenv.h
   haiku/trunk/src/system/libroot/posix/fenv/
   haiku/trunk/src/system/libroot/posix/fenv/arm/
   haiku/trunk/src/system/libroot/posix/fenv/arm/fenv.c
   haiku/trunk/src/system/libroot/posix/fenv/i387/
   haiku/trunk/src/system/libroot/posix/fenv/i387/fenv.c
   haiku/trunk/src/system/libroot/posix/fenv/powerpc/
   haiku/trunk/src/system/libroot/posix/fenv/powerpc/fenv.c
Modified:
   haiku/trunk/src/system/libroot/Jamfile
   haiku/trunk/src/system/libroot/posix/Jamfile
Log:
Added FreeBSD fenv implementation - tested with dmd port, seems that it works

Added: haiku/trunk/headers/posix/arch/arm/fenv.h
===================================================================
--- haiku/trunk/headers/posix/arch/arm/fenv.h                           (rev 0)
+++ haiku/trunk/headers/posix/arch/arm/fenv.h   2010-02-09 06:09:28 UTC (rev 
35437)
@@ -0,0 +1,218 @@
+/*-
+ * Copyright (c) 2004-2005 David Schultz <das@xxxxxxxxxxx>
+ * 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$
+ */
+
+#ifndef        _FENV_H_
+#define        _FENV_H_
+
+#include <sys/types.h>
+#include <SupportDefs.h>
+
+typedef        uint32  fenv_t;
+typedef        uint32  fexcept_t;
+
+/* Exception flags */
+#define        FE_INVALID      0x0001
+#define        FE_DIVBYZERO    0x0002
+#define        FE_OVERFLOW     0x0004
+#define        FE_UNDERFLOW    0x0008
+#define        FE_INEXACT      0x0010
+#define        FE_ALL_EXCEPT   (FE_DIVBYZERO | FE_INEXACT | \
+                        FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
+
+/* Rounding modes */
+#define        FE_TONEAREST    0x0000
+#define        FE_TOWARDZERO   0x0001
+#define        FE_UPWARD       0x0002
+#define        FE_DOWNWARD     0x0003
+#define        _ROUND_MASK     (FE_TONEAREST | FE_DOWNWARD | \
+                        FE_UPWARD | FE_TOWARDZERO)
+__BEGIN_DECLS
+
+/* Default floating-point environment */
+extern const fenv_t    __fe_dfl_env;
+#define        FE_DFL_ENV      (&__fe_dfl_env)
+
+/* We need to be able to map status flag positions to mask flag positions */
+#define _FPUSW_SHIFT   16
+#define        _ENABLE_MASK    (FE_ALL_EXCEPT << _FPUSW_SHIFT)
+
+#ifdef ARM_HARD_FLOAT
+#define        __rfs(__fpsr)   __asm __volatile("rfs %0" : "=r" (*(__fpsr)))
+#define        __wfs(__fpsr)   __asm __volatile("wfs %0" : : "r" (__fpsr))
+#else
+#define __rfs(__fpsr)
+#define __wfs(__fpsr)
+#endif
+
+static __inline int
+feclearexcept(int __excepts)
+{
+       fexcept_t __fpsr;
+
+       __rfs(&__fpsr);
+       __fpsr &= ~__excepts;
+       __wfs(__fpsr);
+       return (0);
+}
+
+static __inline int
+fegetexceptflag(fexcept_t *__flagp, int __excepts)
+{
+       fexcept_t __fpsr;
+
+       __rfs(&__fpsr);
+       *__flagp = __fpsr & __excepts;
+       return (0);
+}
+
+static __inline int
+fesetexceptflag(const fexcept_t *__flagp, int __excepts)
+{
+       fexcept_t __fpsr;
+
+       __rfs(&__fpsr);
+       __fpsr &= ~__excepts;
+       __fpsr |= *__flagp & __excepts;
+       __wfs(__fpsr);
+       return (0);
+}
+
+static __inline int
+feraiseexcept(int __excepts)
+{
+       fexcept_t __ex = __excepts;
+
+       fesetexceptflag(&__ex, __excepts);      /* XXX */
+       return (0);
+}
+
+static __inline int
+fetestexcept(int __excepts)
+{
+       fexcept_t __fpsr;
+
+       __rfs(&__fpsr);
+       return (__fpsr & __excepts);
+}
+
+static __inline int
+fegetround(void)
+{
+
+       /*
+        * Apparently, the rounding mode is specified as part of the
+        * instruction format on ARM, so the dynamic rounding mode is
+        * indeterminate.  Some FPUs may differ.
+        */
+       return (-1);
+}
+
+static __inline int
+fesetround(int __round)
+{
+
+       return (-1);
+}
+
+static __inline int
+fegetenv(fenv_t *__envp)
+{
+
+       __rfs(__envp);
+       return (0);
+}
+
+static __inline int
+feholdexcept(fenv_t *__envp)
+{
+       fenv_t __env;
+
+       __rfs(&__env);
+       *__envp = __env;
+       __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
+       __wfs(__env);
+       return (0);
+}
+
+static __inline int
+fesetenv(const fenv_t *__envp)
+{
+
+       __wfs(*__envp);
+       return (0);
+}
+
+static __inline int
+feupdateenv(const fenv_t *__envp)
+{
+       fexcept_t __fpsr;
+
+       __rfs(&__fpsr);
+       __wfs(*__envp);
+       feraiseexcept(__fpsr & FE_ALL_EXCEPT);
+       return (0);
+}
+
+#if __BSD_VISIBLE
+
+static __inline int
+feenableexcept(int __mask)
+{
+       fenv_t __old_fpsr, __new_fpsr;
+
+       __rfs(&__old_fpsr);
+       __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT;
+       __wfs(__new_fpsr);
+       return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+}
+
+static __inline int
+fedisableexcept(int __mask)
+{
+       fenv_t __old_fpsr, __new_fpsr;
+
+       __rfs(&__old_fpsr);
+       __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
+       __wfs(__new_fpsr);
+       return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+}
+
+static __inline int
+fegetexcept(void)
+{
+       fenv_t __fpsr;
+
+       __rfs(&__fpsr);
+       return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT);
+}
+
+#endif /* __BSD_VISIBLE */
+
+__END_DECLS
+
+#endif /* !_FENV_H_ */

Added: haiku/trunk/headers/posix/arch/ppc/fenv.h
===================================================================
--- haiku/trunk/headers/posix/arch/ppc/fenv.h                           (rev 0)
+++ haiku/trunk/headers/posix/arch/ppc/fenv.h   2010-02-09 06:09:28 UTC (rev 
35437)
@@ -0,0 +1,269 @@
+/*-
+ * Copyright (c) 2004-2005 David Schultz <das@xxxxxxxxxxx>
+ * 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$
+ */
+
+#ifndef        _FENV_H_
+#define        _FENV_H_
+
+#include <sys/types.h>
+#include <SupportDefs.h>
+
+typedef        uint32  fenv_t;
+typedef        uint32  fexcept_t;
+
+/* Exception flags */
+#define        FE_INEXACT      0x02000000
+#define        FE_DIVBYZERO    0x04000000
+#define        FE_UNDERFLOW    0x08000000
+#define        FE_OVERFLOW     0x10000000
+#define        FE_INVALID      0x20000000      /* all types of invalid FP ops 
*/
+
+/*
+ * The PowerPC architecture has extra invalid flags that indicate the
+ * specific type of invalid operation occurred.  These flags may be
+ * tested, set, and cleared---but not masked---separately.  All of
+ * these bits are cleared when FE_INVALID is cleared, but only
+ * FE_VXSOFT is set when FE_INVALID is explicitly set in software.
+ */
+#define        FE_VXCVI        0x00000100      /* invalid integer convert */
+#define        FE_VXSQRT       0x00000200      /* square root of a negative */
+#define        FE_VXSOFT       0x00000400      /* software-requested exception 
*/
+#define        FE_VXVC         0x00080000      /* ordered comparison involving 
NaN */
+#define        FE_VXIMZ        0x00100000      /* inf * 0 */
+#define        FE_VXZDZ        0x00200000      /* 0 / 0 */
+#define        FE_VXIDI        0x00400000      /* inf / inf */
+#define        FE_VXISI        0x00800000      /* inf - inf */
+#define        FE_VXSNAN       0x01000000      /* operation on a signalling 
NaN */
+#define        FE_ALL_INVALID  (FE_VXCVI | FE_VXSQRT | FE_VXSOFT | FE_VXVC | \
+                        FE_VXIMZ | FE_VXZDZ | FE_VXIDI | FE_VXISI | \
+                        FE_VXSNAN | FE_INVALID)
+#define        FE_ALL_EXCEPT   (FE_DIVBYZERO | FE_INEXACT | \
+                        FE_ALL_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
+
+/* Rounding modes */
+#define        FE_TONEAREST    0x0000
+#define        FE_TOWARDZERO   0x0001
+#define        FE_UPWARD       0x0002
+#define        FE_DOWNWARD     0x0003
+#define        _ROUND_MASK     (FE_TONEAREST | FE_DOWNWARD | \
+                        FE_UPWARD | FE_TOWARDZERO)
+
+__BEGIN_DECLS
+
+/* Default floating-point environment */
+extern const fenv_t    __fe_dfl_env;
+#define        FE_DFL_ENV      (&__fe_dfl_env)
+
+/* We need to be able to map status flag positions to mask flag positions */
+#define        _FPUSW_SHIFT    22
+#define        _ENABLE_MASK    ((FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
+                        FE_OVERFLOW | FE_UNDERFLOW) >> _FPUSW_SHIFT)
+
+#ifndef _SOFT_FLOAT
+#define        __mffs(__env)   __asm __volatile("mffs %0" : "=f" (*(__env)))
+#define        __mtfsf(__env)  __asm __volatile("mtfsf 255,%0" : : "f" (__env))
+#else
+#define        __mffs(__env)
+#define        __mtfsf(__env)
+#endif
+
+union __fpscr {
+       double __d;
+       struct {
+               __uint32_t __junk;
+               fenv_t __reg;
+       } __bits;
+};
+
+static __inline int
+feclearexcept(int __excepts)
+{
+       union __fpscr __r;
+
+       if (__excepts & FE_INVALID)
+               __excepts |= FE_ALL_INVALID;
+       __mffs(&__r.__d);
+       __r.__bits.__reg &= ~__excepts;
+       __mtfsf(__r.__d);
+       return (0);
+}
+
+static __inline int
+fegetexceptflag(fexcept_t *__flagp, int __excepts)
+{
+       union __fpscr __r;
+
+       __mffs(&__r.__d);
+       *__flagp = __r.__bits.__reg & __excepts;
+       return (0);
+}
+
+static __inline int
+fesetexceptflag(const fexcept_t *__flagp, int __excepts)
+{
+       union __fpscr __r;
+
+       if (__excepts & FE_INVALID)
+               __excepts |= FE_ALL_EXCEPT;
+       __mffs(&__r.__d);
+       __r.__bits.__reg &= ~__excepts;
+       __r.__bits.__reg |= *__flagp & __excepts;
+       __mtfsf(__r.__d);
+       return (0);
+}
+
+static __inline int
+feraiseexcept(int __excepts)
+{
+       union __fpscr __r;
+
+       if (__excepts & FE_INVALID)
+               __excepts |= FE_VXSOFT;
+       __mffs(&__r.__d);
+       __r.__bits.__reg |= __excepts;
+       __mtfsf(__r.__d);
+       return (0);
+}
+
+static __inline int
+fetestexcept(int __excepts)
+{
+       union __fpscr __r;
+
+       __mffs(&__r.__d);
+       return (__r.__bits.__reg & __excepts);
+}
+
+static __inline int
+fegetround(void)
+{
+       union __fpscr __r;
+
+       __mffs(&__r.__d);
+       return (__r.__bits.__reg & _ROUND_MASK);
+}
+
+static __inline int
+fesetround(int __round)
+{
+       union __fpscr __r;
+
+       if (__round & ~_ROUND_MASK)
+               return (-1);
+       __mffs(&__r.__d);
+       __r.__bits.__reg &= ~_ROUND_MASK;
+       __r.__bits.__reg |= __round;
+       __mtfsf(__r.__d);
+       return (0);
+}
+
+static __inline int
+fegetenv(fenv_t *__envp)
+{
+       union __fpscr __r;
+
+       __mffs(&__r.__d);
+       *__envp = __r.__bits.__reg;
+       return (0);
+}
+
+static __inline int
+feholdexcept(fenv_t *__envp)
+{
+       union __fpscr __r;
+
+       __mffs(&__r.__d);
+       *__envp = __r.__d;
+       __r.__bits.__reg &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
+       __mtfsf(__r.__d);
+       return (0);
+}
+
+static __inline int
+fesetenv(const fenv_t *__envp)
+{
+       union __fpscr __r;
+
+       __r.__bits.__reg = *__envp;
+       __mtfsf(__r.__d);
+       return (0);
+}
+
+static __inline int
+feupdateenv(const fenv_t *__envp)
+{
+       union __fpscr __r;
+
+       __mffs(&__r.__d);
+       __r.__bits.__reg &= FE_ALL_EXCEPT;
+       __r.__bits.__reg |= *__envp;
+       __mtfsf(__r.__d);
+       return (0);
+}
+
+#if __BSD_VISIBLE
+
+static __inline int
+feenableexcept(int __mask)
+{
+       union __fpscr __r;
+       fenv_t __oldmask;
+
+       __mffs(&__r.__d);
+       __oldmask = __r.__bits.__reg;
+       __r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT;
+       __mtfsf(__r.__d);
+       return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
+}
+
+static __inline int
+fedisableexcept(int __mask)
+{
+       union __fpscr __r;
+       fenv_t __oldmask;
+
+       __mffs(&__r.__d);
+       __oldmask = __r.__bits.__reg;
+       __r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT);
+       __mtfsf(__r.__d);
+       return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
+}
+
+static __inline int
+fegetexcept(void)
+{
+       union __fpscr __r;
+
+       __mffs(&__r.__d);
+       return ((__r.__bits.__reg & _ENABLE_MASK) << _FPUSW_SHIFT);
+}
+
+#endif /* __BSD_VISIBLE */
+
+__END_DECLS
+
+#endif /* !_FENV_H_ */

Added: haiku/trunk/headers/posix/arch/x86/fenv.h
===================================================================
--- haiku/trunk/headers/posix/arch/x86/fenv.h                           (rev 0)
+++ haiku/trunk/headers/posix/arch/x86/fenv.h   2010-02-09 06:09:28 UTC (rev 
35437)
@@ -0,0 +1,252 @@
+/*-
+ * Copyright (c) 2004-2005 David Schultz <das@xxxxxxxxxxx>
+ * 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$
+ */
+
+#ifndef        _FENV_H_
+#define        _FENV_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <SupportDefs.h>
+
+/*                   
+ * To preserve binary compatibility with FreeBSD 5.3, we pack the
+ * mxcsr into some reserved fields, rather than changing sizeof(fenv_t).
+ */
+typedef struct {
+       uint16  __control;
+       uint16  __mxcsr_hi;
+       uint16  __status;
+       uint16  __mxcsr_lo;
+       uint32  __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)(x) >> 16;           \
+       (env).__mxcsr_lo = (uint16)(x);                 \
+} while (0)
+
+typedef        uint16  fexcept_t;
+
+/* Exception flags */
+#define        FE_INVALID      0x01
+#define        FE_DENORMAL     0x02
+#define        FE_DIVBYZERO    0x04
+#define        FE_OVERFLOW     0x08
+#define        FE_UNDERFLOW    0x10
+#define        FE_INEXACT      0x20
+#define        FE_ALL_EXCEPT   (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
+                        FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
+
+/* Rounding modes */
+#define        FE_TONEAREST    0x0000
+#define        FE_DOWNWARD     0x0400
+#define        FE_UPWARD       0x0800
+#define        FE_TOWARDZERO   0x0c00
+#define        _ROUND_MASK     (FE_TONEAREST | FE_DOWNWARD | \
+                        FE_UPWARD | FE_TOWARDZERO)
+
+/*
+ * As compared to the x87 control word, the SSE unit's control word
+ * has the rounding control bits offset by 3 and the exception mask
+ * bits offset by 7.
+ */
+#define        _SSE_ROUND_SHIFT        3
+#define        _SSE_EMASK_SHIFT        7
+
+__BEGIN_DECLS
+
+/* After testing for SSE support once, we cache the result in __has_sse. */
+enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK };
+extern enum __sse_support __has_sse;
+int __test_sse(void);
+#ifdef __SSE__
+#define        __HAS_SSE()     1
+#else
+#define        __HAS_SSE()     (__has_sse == __SSE_YES ||                      
\
+                        (__has_sse == __SSE_UNK && __test_sse()))
+#endif
+
+/* Default floating-point environment */
+extern const fenv_t    __fe_dfl_env;
+#define        FE_DFL_ENV      (&__fe_dfl_env)
+
+#define        __fldcw(__cw)           __asm __volatile("fldcw %0" : : "m" 
(__cw))
+#define        __fldenv(__env)         __asm __volatile("fldenv %0" : : "m" 
(__env))
+#define        __fldenvx(__env)        __asm __volatile("fldenv %0" : : "m" 
(__env)  \
+                               : "st", "st(1)", "st(2)", "st(3)", "st(4)",   \
+                               "st(5)", "st(6)", "st(7)")
+#define        __fnclex()              __asm __volatile("fnclex")
+#define        __fnstenv(__env)        __asm __volatile("fnstenv %0" : "=m" 
(*(__env)))
+#define        __fnstcw(__cw)          __asm __volatile("fnstcw %0" : "=m" 
(*(__cw)))
+#define        __fnstsw(__sw)          __asm __volatile("fnstsw %0" : "=m" 
(*(__sw)))
+#define        __fwait()               __asm __volatile("fwait")
+#define        __ldmxcsr(__csr)        __asm __volatile("ldmxcsr %0" : : "m" 
(__csr))
+#define        __stmxcsr(__csr)        __asm __volatile("stmxcsr %0" : "=m" 
(*(__csr)))
+
+static __inline int
+feclearexcept(int __excepts)
+{
+       fenv_t __env;
+       short __mxcsr;
+
+       if (__excepts == FE_ALL_EXCEPT) {
+               __fnclex();
+       } else {
+               __fnstenv(&__env);
+               __env.__status &= ~__excepts;
+               __fldenv(__env);
+       }
+       if (__HAS_SSE()) {
+               __stmxcsr(&__mxcsr);
+               __mxcsr &= ~__excepts;
+               __ldmxcsr(__mxcsr);
+       }
+       return (0);
+}
+
+static __inline int
+fegetexceptflag(fexcept_t *__flagp, int __excepts)
+{
+       int __mxcsr, __status;
+
+       __fnstsw(&__status);
+       if (__HAS_SSE())
+               __stmxcsr(&__mxcsr);
+       else
+               __mxcsr = 0;
+       *__flagp = (__mxcsr | __status) & __excepts;
+       return (0);
+}
+
+int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
+int feraiseexcept(int __excepts);
+
+static __inline int
+fetestexcept(int __excepts)
+{
+       int __mxcsr, __status;
+
+       __fnstsw(&__status);
+       if (__HAS_SSE())
+               __stmxcsr(&__mxcsr);
+       else
+               __mxcsr = 0;
+       return ((__status | __mxcsr) & __excepts);
+}
+
+static __inline int
+fegetround(void)
+{
+       int __control;
+
+       /*
+        * We assume that the x87 and the SSE unit agree on the
+        * rounding mode.  Reading the control word on the x87 turns
+        * out to be about 5 times faster than reading it on the SSE
+        * unit on an Opteron 244.
+        */
+       __fnstcw(&__control);
+       return (__control & _ROUND_MASK);
+}
+
+static __inline int
+fesetround(int __round)
+{
+       int __mxcsr, __control;
+
+       if (__round & ~_ROUND_MASK)
+               return (-1);
+
+       __fnstcw(&__control);
+       __control &= ~_ROUND_MASK;
+       __control |= __round;
+       __fldcw(__control);
+
+       if (__HAS_SSE()) {
+               __stmxcsr(&__mxcsr);
+               __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
+               __mxcsr |= __round << _SSE_ROUND_SHIFT;
+               __ldmxcsr(__mxcsr);
+       }
+
+       return (0);
+}
+
+int fegetenv(fenv_t *__envp);
+int feholdexcept(fenv_t *__envp);
+
+static __inline int
+fesetenv(const fenv_t *__envp)
+{
+       fenv_t __env = *__envp;
+       int __mxcsr;
+
+       __mxcsr = __get_mxcsr(__env);
+       __set_mxcsr(__env, 0xffffffff);
+       /*
+        * XXX Using fldenvx() instead of fldenv() tells the compiler that this
+        * instruction clobbers the i387 register stack.  This happens because
+        * we restore the tag word from the saved environment.  Normally, this
+        * would happen anyway and we wouldn't care, because the ABI allows
+        * function calls to clobber the i387 regs.  However, fesetenv() is
+        * inlined, so we need to be more careful.
+        */
+       __fldenvx(__env);
+       if (__HAS_SSE())
+               __ldmxcsr(__mxcsr);
+       return (0);
+}
+
+int feupdateenv(const fenv_t *__envp);
+
+#if __BSD_VISIBLE
+
+int feenableexcept(int __mask);
+int fedisableexcept(int __mask);
+
+static __inline int
+fegetexcept(void)
+{
+       int __control;
+
+       /*
+        * We assume that the masks for the x87 and the SSE unit are
+        * the same.
+        */
+       __fnstcw(&__control);
+       return (~__control & FE_ALL_EXCEPT);
+}
+
+#endif /* __BSD_VISIBLE */
+
+__END_DECLS
+
+#endif /* !_FENV_H_ */

Added: haiku/trunk/headers/posix/arch/x86/npx.h
===================================================================
--- haiku/trunk/headers/posix/arch/x86/npx.h                            (rev 0)
+++ haiku/trunk/headers/posix/arch/x86/npx.h    2010-02-09 06:09:28 UTC (rev 
35437)
@@ -0,0 +1,163 @@
+/*-
+ * 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$
+ */
+
+/*
+ * 287/387 NPX Coprocessor Data Structures and Constants
+ * W. Jolitz 1/90
+ */
+
+#ifndef _MACHINE_NPX_H_
+#define        _MACHINE_NPX_H_
+
+#define __aligned(x)    __attribute__((__aligned__(x)))
+
+/* 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 */
+       u_short en_fcs;         /* floating code segment selector */
+       u_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 */
+       u_long  fp_mantlo;      /* mantissa low (31:0) */
+       u_long  fp_manthi;      /* mantissa high (63:32) */
+       int     fp_exp:15;      /* exponent */
+       int     fp_sgn:1;       /* mantissa sign */
+#else
+       u_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 */
+       u_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).
+        */
+       u_char  sv_pad[64];     /* padding; used by emulators */
+};
+
+struct  envxmm {
+       uint16  en_cw;          /* control word (16bits) */
+       uint16  en_sw;          /* status word (16bits) */
+       uint16  en_tw;          /* tag word (16bits) */
+       uint16  en_opcode;      /* opcode last executed (11 bits ) */
+       uint32  en_fip;         /* floating point instruction pointer */
+       uint16  en_fcs;         /* floating code segment selector */
+       uint16  en_pad0;        /* padding */
+       uint32  en_foo;         /* floating operand offset */
+       uint16  en_fos;         /* floating operand segment selector */
+       uint16  en_pad1;        /* padding */
+       uint32  en_mxcsr;       /* SSE control/status register */
+       uint32  en_mxcsr_mask;  /* valid bits in mxcsr */
+};
+
+/* Contents of each SSE extended accumulator */
+struct  xmmacc {
+       u_char  xmm_bytes[16];
+};
+
+struct  savexmm {
+       struct  envxmm  sv_env;
+       struct {
+               struct fpacc87  fp_acc;
+               u_char          fp_pad[6];      /* padding */
+       } sv_fp[8];
+       struct xmmacc   sv_xmm[8];
+       u_char sv_pad[224];
+} __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(void);
+void   npxsave(union savefpu *addr);
+void   npxsetregs(struct thread *td, union savefpu *addr);
+int    npxtrap(void);
+
+#endif
+
+#endif /* !_MACHINE_NPX_H_ */

Added: haiku/trunk/headers/posix/fenv.h
===================================================================
--- haiku/trunk/headers/posix/fenv.h                            (rev 0)
+++ haiku/trunk/headers/posix/fenv.h    2010-02-09 06:09:28 UTC (rev 35437)
@@ -0,0 +1,15 @@
+#ifndef _FENV_H
+#define _FENV_H
+
+#if defined(_X86_)
+#  include <arch/x86/fenv.h>
+#elif defined(__ARM__)
+#  include <arch/arm/fenv.h>
+#elif defined(__POWERPC__)
+#  include <arch/ppc/fenv.h>
+#else
+#  error There is no fenv.h for this architecture!
+#endif
+
+#endif /* _FENV_H */
+

Modified: haiku/trunk/src/system/libroot/Jamfile
===================================================================
--- haiku/trunk/src/system/libroot/Jamfile      2010-02-09 05:32:43 UTC (rev 
35436)
+++ haiku/trunk/src/system/libroot/Jamfile      2010-02-09 06:09:28 UTC (rev 
35437)
@@ -15,6 +15,7 @@
        posix_crypt.o
        posix_locale.o
        posix_main.o
+       posix_fenv.o
        posix_pthread.o
        posix_signal.o
        posix_stdio.o

Modified: haiku/trunk/src/system/libroot/posix/Jamfile
===================================================================
--- haiku/trunk/src/system/libroot/posix/Jamfile        2010-02-09 05:32:43 UTC 
(rev 35436)
+++ haiku/trunk/src/system/libroot/posix/Jamfile        2010-02-09 06:09:28 UTC 
(rev 35437)
@@ -30,6 +30,17 @@
        utime.c
 ;
 
+if $(TARGET_ARCH) = x86 {
+       SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src system libroot posix fenv 
i387 ] ;
+} else if $(TARGET_ARCH) = ppc {
+       SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src system libroot posix fenv 
powerpc ] ;
+} else if $(TARGET_ARCH) = arm {
+       SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src system libroot posix fenv 
arm ] ;
+}
+MergeObject posix_fenv.o :
+       fenv.c
+;
+
 SubInclude HAIKU_TOP src system libroot posix arch $(TARGET_ARCH) ;
 
 SubInclude HAIKU_TOP src system libroot posix crypt ;

Added: haiku/trunk/src/system/libroot/posix/fenv/arm/fenv.c
===================================================================
--- haiku/trunk/src/system/libroot/posix/fenv/arm/fenv.c                        
        (rev 0)
+++ haiku/trunk/src/system/libroot/posix/fenv/arm/fenv.c        2010-02-09 
06:09:28 UTC (rev 35437)
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (c) 2004 David Schultz <das@xxxxxxxxxxx>
+ * 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.

[... truncated: 278 lines follow ...]

Other related posts: