]>
Commit | Line | Data |
---|---|---|
d876f532 | 1 | /* Software floating-point emulation. |
568035b7 | 2 | Copyright (C) 1997-2013 Free Software Foundation, Inc. |
d876f532 UD |
3 | This file is part of the GNU C Library. |
4 | Contributed by Richard Henderson (rth@cygnus.com), | |
5 | Jakub Jelinek (jj@ultra.linux.cz), | |
6 | David S. Miller (davem@redhat.com) and | |
7 | Peter Maydell (pmaydell@chiark.greenend.org.uk). | |
8 | ||
9 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
10 | modify it under the terms of the GNU Lesser General Public |
11 | License as published by the Free Software Foundation; either | |
12 | version 2.1 of the License, or (at your option) any later version. | |
d876f532 | 13 | |
638a783c RM |
14 | In addition to the permissions in the GNU Lesser General Public |
15 | License, the Free Software Foundation gives you unlimited | |
16 | permission to link the compiled version of this file into | |
17 | combinations with other programs, and to distribute those | |
18 | combinations without any restriction coming from the use of this | |
19 | file. (The Lesser General Public License restrictions do apply in | |
20 | other respects; for example, they cover modification of the file, | |
21 | and distribution when not linked into a combine executable.) | |
22 | ||
d876f532 UD |
23 | The GNU C Library is distributed in the hope that it will be useful, |
24 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 26 | Lesser General Public License for more details. |
d876f532 | 27 | |
41bdb6e2 | 28 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
29 | License along with the GNU C Library; if not, see |
30 | <http://www.gnu.org/licenses/>. */ | |
d876f532 UD |
31 | |
32 | #ifndef SOFT_FP_H | |
33 | #define SOFT_FP_H | |
34 | ||
fe0b1e85 | 35 | #ifdef _LIBC |
8f480b4b | 36 | #include <sfp-machine.h> |
fe0b1e85 RM |
37 | #else |
38 | #include "sfp-machine.h" | |
39 | #endif | |
d876f532 UD |
40 | |
41 | /* Allow sfp-machine to have its own byte order definitions. */ | |
42 | #ifndef __BYTE_ORDER | |
fe0b1e85 | 43 | #ifdef _LIBC |
d876f532 | 44 | #include <endian.h> |
fe0b1e85 RM |
45 | #else |
46 | #error "endianness not defined by sfp-machine.h" | |
47 | #endif | |
d876f532 UD |
48 | #endif |
49 | ||
50 | #define _FP_WORKBITS 3 | |
51 | #define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) | |
52 | #define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) | |
53 | #define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) | |
54 | #define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) | |
55 | ||
56 | #ifndef FP_RND_NEAREST | |
57 | # define FP_RND_NEAREST 0 | |
58 | # define FP_RND_ZERO 1 | |
59 | # define FP_RND_PINF 2 | |
60 | # define FP_RND_MINF 3 | |
bde40c2f | 61 | #endif |
d876f532 UD |
62 | #ifndef FP_ROUNDMODE |
63 | # define FP_ROUNDMODE FP_RND_NEAREST | |
64 | #endif | |
d876f532 UD |
65 | |
66 | /* By default don't care about exceptions. */ | |
67 | #ifndef FP_EX_INVALID | |
68 | #define FP_EX_INVALID 0 | |
69 | #endif | |
70 | #ifndef FP_EX_OVERFLOW | |
71 | #define FP_EX_OVERFLOW 0 | |
72 | #endif | |
73 | #ifndef FP_EX_UNDERFLOW | |
fe2dcbcc | 74 | #define FP_EX_UNDERFLOW 0 |
d876f532 UD |
75 | #endif |
76 | #ifndef FP_EX_DIVZERO | |
77 | #define FP_EX_DIVZERO 0 | |
78 | #endif | |
79 | #ifndef FP_EX_INEXACT | |
80 | #define FP_EX_INEXACT 0 | |
81 | #endif | |
82 | #ifndef FP_EX_DENORM | |
83 | #define FP_EX_DENORM 0 | |
84 | #endif | |
85 | ||
f775c276 KT |
86 | /* _FP_STRUCT_LAYOUT may be defined as an attribute to determine the |
87 | struct layout variant used for structures where bit-fields are used | |
88 | to access specific parts of binary floating-point numbers. This is | |
89 | required for systems where the default ABI uses struct layout with | |
90 | differences in how consecutive bit-fields are laid out from the | |
91 | default expected by soft-fp. */ | |
92 | #ifndef _FP_STRUCT_LAYOUT | |
93 | #define _FP_STRUCT_LAYOUT | |
94 | #endif | |
95 | ||
d876f532 UD |
96 | #ifdef _FP_DECL_EX |
97 | #define FP_DECL_EX \ | |
98 | int _fex = 0; \ | |
99 | _FP_DECL_EX | |
100 | #else | |
101 | #define FP_DECL_EX int _fex = 0 | |
102 | #endif | |
fe2dcbcc | 103 | |
dcc2dd3f JM |
104 | /* Initialize any machine-specific state used in FP_ROUNDMODE, |
105 | FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS. */ | |
d876f532 UD |
106 | #ifndef FP_INIT_ROUNDMODE |
107 | #define FP_INIT_ROUNDMODE do {} while (0) | |
108 | #endif | |
109 | ||
dcc2dd3f JM |
110 | /* Initialize any machine-specific state used in |
111 | FP_HANDLE_EXCEPTIONS. */ | |
112 | #ifndef FP_INIT_EXCEPTIONS | |
113 | #define FP_INIT_EXCEPTIONS FP_INIT_ROUNDMODE | |
114 | #endif | |
115 | ||
d876f532 UD |
116 | #ifndef FP_HANDLE_EXCEPTIONS |
117 | #define FP_HANDLE_EXCEPTIONS do {} while (0) | |
118 | #endif | |
119 | ||
120 | #ifndef FP_INHIBIT_RESULTS | |
121 | /* By default we write the results always. | |
122 | * sfp-machine may override this and e.g. | |
123 | * check if some exceptions are unmasked | |
124 | * and inhibit it in such a case. | |
125 | */ | |
126 | #define FP_INHIBIT_RESULTS 0 | |
127 | #endif | |
128 | ||
129 | #define FP_SET_EXCEPTION(ex) \ | |
130 | _fex |= (ex) | |
fe2dcbcc | 131 | |
d876f532 UD |
132 | #define FP_UNSET_EXCEPTION(ex) \ |
133 | _fex &= ~(ex) | |
134 | ||
135 | #define FP_CLEAR_EXCEPTIONS \ | |
136 | _fex = 0 | |
137 | ||
ae251b0b DM |
138 | #define FP_CUR_EXCEPTIONS \ |
139 | (_fex) | |
140 | ||
141 | #ifndef FP_TRAPPING_EXCEPTIONS | |
142 | #define FP_TRAPPING_EXCEPTIONS 0 | |
143 | #endif | |
144 | ||
d876f532 UD |
145 | #define _FP_ROUND_NEAREST(wc, X) \ |
146 | do { \ | |
147 | if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ | |
148 | _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ | |
149 | } while (0) | |
150 | ||
8ed1e7d5 | 151 | #define _FP_ROUND_ZERO(wc, X) (void)0 |
d876f532 UD |
152 | |
153 | #define _FP_ROUND_PINF(wc, X) \ | |
154 | do { \ | |
155 | if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ | |
156 | _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ | |
157 | } while (0) | |
158 | ||
159 | #define _FP_ROUND_MINF(wc, X) \ | |
160 | do { \ | |
161 | if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ | |
162 | _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ | |
163 | } while (0) | |
164 | ||
165 | #define _FP_ROUND(wc, X) \ | |
166 | do { \ | |
167 | if (_FP_FRAC_LOW_##wc(X) & 7) \ | |
47594329 MS |
168 | { \ |
169 | FP_SET_EXCEPTION(FP_EX_INEXACT); \ | |
170 | switch (FP_ROUNDMODE) \ | |
171 | { \ | |
172 | case FP_RND_NEAREST: \ | |
173 | _FP_ROUND_NEAREST(wc,X); \ | |
174 | break; \ | |
175 | case FP_RND_ZERO: \ | |
176 | _FP_ROUND_ZERO(wc,X); \ | |
177 | break; \ | |
178 | case FP_RND_PINF: \ | |
179 | _FP_ROUND_PINF(wc,X); \ | |
180 | break; \ | |
181 | case FP_RND_MINF: \ | |
182 | _FP_ROUND_MINF(wc,X); \ | |
183 | break; \ | |
184 | } \ | |
185 | } \ | |
d876f532 UD |
186 | } while (0) |
187 | ||
188 | #define FP_CLS_NORMAL 0 | |
189 | #define FP_CLS_ZERO 1 | |
190 | #define FP_CLS_INF 2 | |
191 | #define FP_CLS_NAN 3 | |
192 | ||
193 | #define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) | |
194 | ||
195 | #include "op-1.h" | |
196 | #include "op-2.h" | |
197 | #include "op-4.h" | |
198 | #include "op-8.h" | |
199 | #include "op-common.h" | |
200 | ||
201 | /* Sigh. Silly things longlong.h needs. */ | |
202 | #define UWtype _FP_W_TYPE | |
203 | #define W_TYPE_SIZE _FP_W_TYPE_SIZE | |
204 | ||
cbc85992 | 205 | typedef int QItype __attribute__((mode(QI))); |
d876f532 UD |
206 | typedef int SItype __attribute__((mode(SI))); |
207 | typedef int DItype __attribute__((mode(DI))); | |
cbc85992 | 208 | typedef unsigned int UQItype __attribute__((mode(QI))); |
d876f532 UD |
209 | typedef unsigned int USItype __attribute__((mode(SI))); |
210 | typedef unsigned int UDItype __attribute__((mode(DI))); | |
211 | #if _FP_W_TYPE_SIZE == 32 | |
212 | typedef unsigned int UHWtype __attribute__((mode(HI))); | |
213 | #elif _FP_W_TYPE_SIZE == 64 | |
214 | typedef USItype UHWtype; | |
215 | #endif | |
216 | ||
ae8e81f5 JJ |
217 | #ifndef CMPtype |
218 | #define CMPtype int | |
219 | #endif | |
220 | ||
fe0b1e85 RM |
221 | #define SI_BITS (__CHAR_BIT__ * (int)sizeof(SItype)) |
222 | #define DI_BITS (__CHAR_BIT__ * (int)sizeof(DItype)) | |
223 | ||
d876f532 | 224 | #ifndef umul_ppmm |
fe0b1e85 | 225 | #ifdef _LIBC |
d876f532 | 226 | #include <stdlib/longlong.h> |
fe0b1e85 RM |
227 | #else |
228 | #include "longlong.h" | |
229 | #endif | |
d876f532 UD |
230 | #endif |
231 | ||
fe0b1e85 | 232 | #ifdef _LIBC |
d57e7471 | 233 | #include <stdlib.h> |
fe0b1e85 RM |
234 | #else |
235 | extern void abort (void); | |
236 | #endif | |
d57e7471 | 237 | |
d876f532 | 238 | #endif |