Update.
[kopensolaris-gnu/glibc.git] / sysdeps / powerpc / bits / fenv.h
1 /* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    The GNU C 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 the GNU C Library; see the file COPYING.LIB.  If not,
16    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 #ifndef _FENV_H
20 # error "Never use <bits/fenv.h> directly; include <fenv.h> instead."
21 #endif
22
23
24 /* Define bits representing the exception.  We use the bit positions of
25    the appropriate bits in the FPSCR...  */
26 enum
27   {
28     FE_INEXACT = 1 << (31 - 6),
29 #define FE_INEXACT      FE_INEXACT
30     FE_DIVBYZERO = 1 << (31 - 5),
31 #define FE_DIVBYZERO    FE_DIVBYZERO
32     FE_UNDERFLOW = 1 << (31 - 4),
33 #define FE_UNDERFLOW    FE_UNDERFLOW
34     FE_OVERFLOW = 1 << (31 - 3),
35 #define FE_OVERFLOW     FE_OVERFLOW
36
37     /* ... except for FE_INVALID, for which we use bit 31. FE_INVALID
38        actually corresponds to bits 7 through 12 and 21 through 23
39        in the FPSCR, but we can't use that because the current draft
40        says that it must be a power of 2.  Instead we use bit 2 which
41        is the summary bit for all the FE_INVALID exceptions, which
42        kind of makes sense.  */
43     FE_INVALID = 1 << (31 - 2),
44 #define FE_INVALID      FE_INVALID
45
46 #ifdef __USE_GNU
47     /* Breakdown of the FE_INVALID bits. Setting FE_INVALID on an
48        input to a routine is equivalent to setting all of these bits;
49        FE_INVALID will be set on output from a routine iff one of
50        these bits is set.  Note, though, that you can't disable or
51        enable these exceptions individually.  */
52
53     /* Operation with SNaN. */
54     FE_INVALID_SNAN = 1 << (31 - 7),
55 # define FE_INVALID_SNAN        FE_INVALID_SNAN
56
57     /* Inf - Inf */
58     FE_INVALID_ISI = 1 << (31 - 8),
59 # define FE_INVALID_ISI         FE_INVALID_ISI
60
61     /* Inf / Inf */
62     FE_INVALID_IDI = 1 << (31 - 9),
63 # define FE_INVALID_IDI         FE_INVALID_IDI
64
65     /* 0 / 0 */
66     FE_INVALID_ZDZ = 1 << (31 - 10),
67 # define FE_INVALID_ZDZ         FE_INVALID_ZDZ
68
69     /* Inf * 0 */
70     FE_INVALID_IMZ = 1 << (31 - 11),
71 # define FE_INVALID_IMZ         FE_INVALID_IMZ
72
73     /* Comparison with NaN or SNaN.  */
74     FE_INVALID_COMPARE = 1 << (31 - 12),
75 # define FE_INVALID_COMPARE     FE_INVALID_COMPARE
76
77     /* Invalid operation flag for software (not set by hardware).  */
78     /* Note that some chips don't have this implemented, presumably
79        because no-one expected anyone to write software for them %-).  */
80     FE_INVALID_SOFTWARE = 1 << (31 - 21),
81 # define FE_INVALID_SOFTWARE    FE_INVALID_SOFTWARE
82
83     /* Square root of negative number (including -Inf).  */
84     /* Note that some chips don't have this implemented.  */
85     FE_INVALID_SQRT = 1 << (31 - 22),
86 # define FE_INVALID_SQRT        FE_INVALID_SQRT
87
88     /* Conversion-to-integer of a NaN or a number too large or too small.  */
89     FE_INVALID_INTEGER_CONVERSION = 1 << (31 - 23),
90 # define FE_INVALID_INTEGER_CONVERSION  FE_INVALID_INTEGER_CONVERSION
91
92 # define FE_ALL_INVALID \
93         (FE_INVALID_SNAN | FE_INVALID_ISI | FE_INVALID_IDI | FE_INVALID_ZDZ \
94          | FE_INVALID_IMZ | FE_INVALID_COMPARE | FE_INVALID_SOFTWARE \
95          | FE_INVALID_SQRT | FE_INVALID_INTEGER_CONVERSION)
96 #endif
97   };
98
99 #define FE_ALL_EXCEPT \
100         (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
101
102 /* PowerPC chips support all of the four defined rounding modes.  We
103    use the bit pattern in the FPSCR as the values for the
104    appropriate macros.  */
105 enum
106   {
107     FE_TONEAREST = 0,
108 #define FE_TONEAREST    FE_TONEAREST
109     FE_TOWARDZERO = 1,
110 #define FE_TOWARDZERO   FE_TOWARDZERO
111     FE_UPWARD = 2,
112 #define FE_UPWARD       FE_UPWARD
113     FE_DOWNWARD = 3,
114 #define FE_DOWNWARD     FE_DOWNWARD
115   };
116
117 /* Type representing exception flags.  */
118 typedef unsigned int fexcept_t;
119
120 /* Type representing floating-point environment.  We leave it as 'double'
121    for efficiency reasons (rather than writing it to a 32-bit integer). */
122 typedef double fenv_t;
123
124 /* If the default argument is used we use this value.  */
125 extern const fenv_t __fe_dfl_env;
126 #define FE_DFL_ENV      (&__fe_dfl_env)
127
128 #ifdef __USE_GNU
129 /* Floating-point environment where all exceptions are enabled.  Note that
130    this is not sufficient to give you SIGFPE.  */
131 extern const fenv_t __fe_enabled_env;
132 # define FE_ENABLED_ENV (&__fe_enabled_env)
133
134 /* Floating-point environment with (processor-dependent) non-IEEE floating
135    point.  */
136 extern const fenv_t __fe_nonieee_env;
137 # define FE_NONIEEE_ENV (&__fe_nonieee_env)
138
139 /* Floating-point environment with all exceptions enabled.  Note that
140    just evaluating this value will set the processor into 'FPU
141    exceptions imprecise recoverable' mode, which may cause a significant
142    performance penalty (but have no other visible effect).  */
143 extern const fenv_t *__fe_nomask_env __P ((void));
144 # define FE_NOMASK_ENV  (__fe_nomask_env ())
145 #endif
146
147 #if defined __OPTIMIZE__ && !defined _SOFT_FLOAT
148 /* Inline definition for fegetround.  */
149 # define fegetround() \
150   (__extension__  ({ int __fegetround_result;                                 \
151                      __asm__ ("mcrfs 7,7 ; mfcr %0"                           \
152                              : "=r"(__fegetround_result) : : "cr7");          \
153                      __fegetround_result & 3; }))
154
155 /* Inline definition for feraiseexcept.  */
156 # define feraiseexcept(__excepts) \
157   (__extension__ ({ if (__builtin_constant_p (__excepts)                      \
158                         && ((__excepts) & -(__excepts)) == 0                  \
159                         && (__excepts) != FE_INVALID) {                       \
160                       if ((__excepts) != 0)                                   \
161                         __asm__ __volatile__                                  \
162                           ("mtfsb1 %0"                                        \
163                            : : "i"(32 - __builtin_ffs (__excepts)));          \
164                     } else                                                    \
165                       (feraiseexcept) (__excepts); }))
166
167 /* Inline definition for feclearexcept.  */
168 # define feclearexcept(__excepts) \
169   (__extension__  ({ if (__builtin_constant_p (__excepts)                     \
170                          && ((__excepts) & -(__excepts)) == 0                 \
171                          && (__excepts) != FE_INVALID) {                      \
172                        if ((__excepts) != 0)                                  \
173                          __asm__ __volatile__                                 \
174                            ("mtfsb0 %0"                                       \
175                             : : "i"(32 - __builtin_ffs (__excepts)));         \
176                      } else                                                   \
177                        (feclearexcept) (__excepts); }))
178 #endif /* __OPTIMIZE__ && !_SOFT_FLOAT */