1 /* GTS - Library for the manipulation of triangulated surfaces
2  * Copyright (C) 1999 St�phane Popinet
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 
20 #include "config.h"
21 
22 #ifdef HAVE_FPU_CONTROL_H
23 #  include <fpu_control.h>
24 #  ifdef _FPU_EXTENDED
25 #   if !defined(__alpha__) || !defined(__GLIBC__)
26 #    if defined(__arm__)
27      static fpu_control_t fpu_round_double = _FPU_DEFAULT;
28 #    else
29      static fpu_control_t fpu_round_double =
30        (_FPU_DEFAULT & ~ _FPU_EXTENDED)|_FPU_DOUBLE;
31 #    endif
32      static fpu_control_t fpu_init;
33 #    define FPU_ROUND_DOUBLE  { _FPU_GETCW(fpu_init);\
34                                 _FPU_SETCW(fpu_round_double); }
35 #    define FPU_RESTORE       {_FPU_SETCW(fpu_init);}
36 #   else /* __alpha__ && __GLIBC__ */
37 #    define FPU_ROUND_DOUBLE
38 #    define FPU_RESTORE
39 #   endif /* __alpha__ && __GLIBC__ */
40 #  else /* not FPU_EXTENDED */
41 #    define FPU_ROUND_DOUBLE
42 #    define FPU_RESTORE
43 #  endif /* not FPU_EXTENDED */
44 #else /* not HAVE_FPU_CONTROL_H */
45 #  ifdef HAVE_FROATINGPOINT_H
46 #    include <floatingpoint.h>
47 #    define FPU_ROUND_DOUBLE  (fpsetprec(FP_PD))
48 #    define FPU_RESTORE       (fpsetprec(FP_PE))
49 #  else /* not HAVE_FROATINGPOINT_H */
50 #    ifdef WIN32
51 #      ifdef _MSC_VER
52 #        include <float.h>
53          static unsigned int fpu_init;
54 #        define FPU_ROUND_DOUBLE (fpu_init = _controlfp (0, 0),\
55                                  _controlfp (_PC_53, MCW_PC))
56 #        define FPU_RESTORE      (_controlfp (fpu_init, 0xfffff))
57 #      elif __MINGW32__
58 #        include <float.h>
59          static unsigned int fpu_init;
60 #        define FPU_ROUND_DOUBLE (fpu_init = _controlfp (0, 0),\
61                                   _controlfp (_PC_53, _MCW_PC))
62 #        define FPU_RESTORE      (_controlfp (fpu_init, 0xfffff))
63 #      else /* not _MSC_VER or __MINGW32__ */
64 #        error "You need MSVC or MinGW for the Win32 version"
65 #      endif /*  not _MSC_VER or __MINGW32__ */
66 #    else /* not WIN32 */
67 #      ifdef __CYGWIN__
68          typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
69          static fpu_control_t fpu_round_double = 0x027f;
70          static fpu_control_t fpu_init;
71 #        define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw))
72 #        define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw))
73 #        define FPU_ROUND_DOUBLE  { _FPU_GETCW(fpu_init);\
74                                     _FPU_SETCW(fpu_round_double); }
75 #        define FPU_RESTORE       { _FPU_SETCW(fpu_init);}
76 #      else /* not __CYGWIN__ */
77 #        ifdef CPP_HAS_WARNING
78 #          warning "Unknown CPU: assuming default double precision rounding"
79 #        endif /* CPP_HAS_WARNING */
80 #        define FPU_ROUND_DOUBLE
81 #        define FPU_RESTORE
82 #      endif /* not __CYGWIN__ */
83 #    endif /* not WIN32 */
84 #  endif /* not __FreeBSD__ */
85 #endif /* not HAVE_FPU_CONTROL_H */
86