2005-12-21 Roland McGrath <roland@redhat.com>
[kopensolaris-gnu/glibc.git] / soft-fp / soft-fp.h
1 /* Software floating-point emulation.
2    Copyright (C) 1997,1998,1999,2000,2002,2003,2005
3         Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5    Contributed by Richard Henderson (rth@cygnus.com),
6                   Jakub Jelinek (jj@ultra.linux.cz),
7                   David S. Miller (davem@redhat.com) and
8                   Peter Maydell (pmaydell@chiark.greenend.org.uk).
9
10    The GNU C Library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 2.1 of the License, or (at your option) any later version.
14
15    The GNU C Library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19
20    You should have received a copy of the GNU Lesser General Public
21    License along with the GNU C Library; if not, write to the Free
22    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23    02111-1307 USA.  */
24
25 #ifndef SOFT_FP_H
26 #define SOFT_FP_H
27
28 #include <sfp-machine.h>
29
30 /* Allow sfp-machine to have its own byte order definitions. */
31 #ifndef __BYTE_ORDER
32 #include <endian.h>
33 #endif
34
35 #define _FP_WORKBITS            3
36 #define _FP_WORK_LSB            ((_FP_W_TYPE)1 << 3)
37 #define _FP_WORK_ROUND          ((_FP_W_TYPE)1 << 2)
38 #define _FP_WORK_GUARD          ((_FP_W_TYPE)1 << 1)
39 #define _FP_WORK_STICKY         ((_FP_W_TYPE)1 << 0)
40
41 #ifndef FP_RND_NEAREST
42 # define FP_RND_NEAREST         0
43 # define FP_RND_ZERO            1
44 # define FP_RND_PINF            2
45 # define FP_RND_MINF            3
46 #endif
47 #ifndef FP_ROUNDMODE
48 # define FP_ROUNDMODE           FP_RND_NEAREST
49 #endif
50
51 /* By default don't care about exceptions. */
52 #ifndef FP_EX_INVALID
53 #define FP_EX_INVALID           0
54 #endif
55 #ifndef FP_EX_OVERFLOW
56 #define FP_EX_OVERFLOW          0
57 #endif
58 #ifndef FP_EX_UNDERFLOW
59 #define FP_EX_UNDERFLOW         0
60 #endif
61 #ifndef FP_EX_DIVZERO
62 #define FP_EX_DIVZERO           0
63 #endif
64 #ifndef FP_EX_INEXACT
65 #define FP_EX_INEXACT           0
66 #endif
67 #ifndef FP_EX_DENORM
68 #define FP_EX_DENORM            0
69 #endif
70
71 #ifdef _FP_DECL_EX
72 #define FP_DECL_EX                                      \
73   int _fex = 0;                                         \
74   _FP_DECL_EX
75 #else
76 #define FP_DECL_EX int _fex = 0
77 #endif
78
79 #ifndef FP_INIT_ROUNDMODE
80 #define FP_INIT_ROUNDMODE do {} while (0)
81 #endif
82
83 #ifndef FP_HANDLE_EXCEPTIONS
84 #define FP_HANDLE_EXCEPTIONS do {} while (0)
85 #endif
86
87 #ifndef FP_INHIBIT_RESULTS
88 /* By default we write the results always.
89  * sfp-machine may override this and e.g.
90  * check if some exceptions are unmasked
91  * and inhibit it in such a case.
92  */
93 #define FP_INHIBIT_RESULTS 0
94 #endif
95
96 #define FP_SET_EXCEPTION(ex)                            \
97   _fex |= (ex)
98
99 #define FP_UNSET_EXCEPTION(ex)                          \
100   _fex &= ~(ex)
101
102 #define FP_CLEAR_EXCEPTIONS                             \
103   _fex = 0
104
105 #define _FP_ROUND_NEAREST(wc, X)                        \
106 do {                                                    \
107     if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND)  \
108       _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);            \
109 } while (0)
110
111 #define _FP_ROUND_ZERO(wc, X)           (void)0
112
113 #define _FP_ROUND_PINF(wc, X)                           \
114 do {                                                    \
115     if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7))           \
116       _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);              \
117 } while (0)
118
119 #define _FP_ROUND_MINF(wc, X)                           \
120 do {                                                    \
121     if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7))            \
122       _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);              \
123 } while (0)
124
125 #define _FP_ROUND(wc, X)                        \
126 do {                                            \
127         if (_FP_FRAC_LOW_##wc(X) & 7)           \
128           FP_SET_EXCEPTION(FP_EX_INEXACT);      \
129         switch (FP_ROUNDMODE)                   \
130         {                                       \
131           case FP_RND_NEAREST:                  \
132             _FP_ROUND_NEAREST(wc,X);            \
133             break;                              \
134           case FP_RND_ZERO:                     \
135             _FP_ROUND_ZERO(wc,X);               \
136             break;                              \
137           case FP_RND_PINF:                     \
138             _FP_ROUND_PINF(wc,X);               \
139             break;                              \
140           case FP_RND_MINF:                     \
141             _FP_ROUND_MINF(wc,X);               \
142             break;                              \
143         }                                       \
144 } while (0)
145
146 #define FP_CLS_NORMAL           0
147 #define FP_CLS_ZERO             1
148 #define FP_CLS_INF              2
149 #define FP_CLS_NAN              3
150
151 #define _FP_CLS_COMBINE(x,y)    (((x) << 2) | (y))
152
153 #include "op-1.h"
154 #include "op-2.h"
155 #include "op-4.h"
156 #include "op-8.h"
157 #include "op-common.h"
158
159 /* Sigh.  Silly things longlong.h needs.  */
160 #define UWtype          _FP_W_TYPE
161 #define W_TYPE_SIZE     _FP_W_TYPE_SIZE
162
163 typedef int QItype __attribute__((mode(QI)));
164 typedef int SItype __attribute__((mode(SI)));
165 typedef int DItype __attribute__((mode(DI)));
166 typedef unsigned int UQItype __attribute__((mode(QI)));
167 typedef unsigned int USItype __attribute__((mode(SI)));
168 typedef unsigned int UDItype __attribute__((mode(DI)));
169 #if _FP_W_TYPE_SIZE == 32
170 typedef unsigned int UHWtype __attribute__((mode(HI)));
171 #elif _FP_W_TYPE_SIZE == 64
172 typedef USItype UHWtype;
173 #endif
174
175 #ifndef umul_ppmm
176 #include <stdlib/longlong.h>
177 #endif
178
179 #include <stdlib.h>
180
181 #endif