floatformat.c revision 1.1.1.1.8.2 1 1.1.1.1.8.2 tls /* IEEE floating point support routines, for GDB, the GNU Debugger.
2 1.1.1.1.8.2 tls Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006
3 1.1.1.1.8.2 tls Free Software Foundation, Inc.
4 1.1.1.1.8.2 tls
5 1.1.1.1.8.2 tls This file is part of GDB.
6 1.1.1.1.8.2 tls
7 1.1.1.1.8.2 tls This program is free software; you can redistribute it and/or modify
8 1.1.1.1.8.2 tls it under the terms of the GNU General Public License as published by
9 1.1.1.1.8.2 tls the Free Software Foundation; either version 2 of the License, or
10 1.1.1.1.8.2 tls (at your option) any later version.
11 1.1.1.1.8.2 tls
12 1.1.1.1.8.2 tls This program is distributed in the hope that it will be useful,
13 1.1.1.1.8.2 tls but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1.1.1.8.2 tls MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1.1.1.8.2 tls GNU General Public License for more details.
16 1.1.1.1.8.2 tls
17 1.1.1.1.8.2 tls You should have received a copy of the GNU General Public License
18 1.1.1.1.8.2 tls along with this program; if not, write to the Free Software
19 1.1.1.1.8.2 tls Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20 1.1.1.1.8.2 tls
21 1.1.1.1.8.2 tls /* This is needed to pick up the NAN macro on some systems. */
22 1.1.1.1.8.2 tls #define _GNU_SOURCE
23 1.1.1.1.8.2 tls
24 1.1.1.1.8.2 tls #ifdef HAVE_CONFIG_H
25 1.1.1.1.8.2 tls #include "config.h"
26 1.1.1.1.8.2 tls #endif
27 1.1.1.1.8.2 tls
28 1.1.1.1.8.2 tls #include <math.h>
29 1.1.1.1.8.2 tls
30 1.1.1.1.8.2 tls #ifdef HAVE_STRING_H
31 1.1.1.1.8.2 tls #include <string.h>
32 1.1.1.1.8.2 tls #endif
33 1.1.1.1.8.2 tls
34 1.1.1.1.8.2 tls /* On some platforms, <float.h> provides DBL_QNAN. */
35 1.1.1.1.8.2 tls #ifdef STDC_HEADERS
36 1.1.1.1.8.2 tls #include <float.h>
37 1.1.1.1.8.2 tls #endif
38 1.1.1.1.8.2 tls
39 1.1.1.1.8.2 tls #include "ansidecl.h"
40 1.1.1.1.8.2 tls #include "libiberty.h"
41 1.1.1.1.8.2 tls #include "floatformat.h"
42 1.1.1.1.8.2 tls
43 1.1.1.1.8.2 tls #ifndef INFINITY
44 1.1.1.1.8.2 tls #ifdef HUGE_VAL
45 1.1.1.1.8.2 tls #define INFINITY HUGE_VAL
46 1.1.1.1.8.2 tls #else
47 1.1.1.1.8.2 tls #define INFINITY (1.0 / 0.0)
48 1.1.1.1.8.2 tls #endif
49 1.1.1.1.8.2 tls #endif
50 1.1.1.1.8.2 tls
51 1.1.1.1.8.2 tls #ifndef NAN
52 1.1.1.1.8.2 tls #ifdef DBL_QNAN
53 1.1.1.1.8.2 tls #define NAN DBL_QNAN
54 1.1.1.1.8.2 tls #else
55 1.1.1.1.8.2 tls #define NAN (0.0 / 0.0)
56 1.1.1.1.8.2 tls #endif
57 1.1.1.1.8.2 tls #endif
58 1.1.1.1.8.2 tls
59 1.1.1.1.8.2 tls static int mant_bits_set (const struct floatformat *, const unsigned char *);
60 1.1.1.1.8.2 tls static unsigned long get_field (const unsigned char *,
61 1.1.1.1.8.2 tls enum floatformat_byteorders,
62 1.1.1.1.8.2 tls unsigned int,
63 1.1.1.1.8.2 tls unsigned int,
64 1.1.1.1.8.2 tls unsigned int);
65 1.1.1.1.8.2 tls static int floatformat_always_valid (const struct floatformat *fmt,
66 1.1.1.1.8.2 tls const void *from);
67 1.1.1.1.8.2 tls
68 1.1.1.1.8.2 tls static int
69 1.1.1.1.8.2 tls floatformat_always_valid (const struct floatformat *fmt ATTRIBUTE_UNUSED,
70 1.1.1.1.8.2 tls const void *from ATTRIBUTE_UNUSED)
71 1.1.1.1.8.2 tls {
72 1.1.1.1.8.2 tls return 1;
73 1.1.1.1.8.2 tls }
74 1.1.1.1.8.2 tls
75 1.1.1.1.8.2 tls /* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
76 1.1.1.1.8.2 tls going to bother with trying to muck around with whether it is defined in
77 1.1.1.1.8.2 tls a system header, what we do if not, etc. */
78 1.1.1.1.8.2 tls #define FLOATFORMAT_CHAR_BIT 8
79 1.1.1.1.8.2 tls
80 1.1.1.1.8.2 tls /* floatformats for IEEE single and double, big and little endian. */
81 1.1.1.1.8.2 tls const struct floatformat floatformat_ieee_single_big =
82 1.1.1.1.8.2 tls {
83 1.1.1.1.8.2 tls floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23,
84 1.1.1.1.8.2 tls floatformat_intbit_no,
85 1.1.1.1.8.2 tls "floatformat_ieee_single_big",
86 1.1.1.1.8.2 tls floatformat_always_valid,
87 1.1.1.1.8.2 tls NULL
88 1.1.1.1.8.2 tls };
89 1.1.1.1.8.2 tls const struct floatformat floatformat_ieee_single_little =
90 1.1.1.1.8.2 tls {
91 1.1.1.1.8.2 tls floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23,
92 1.1.1.1.8.2 tls floatformat_intbit_no,
93 1.1.1.1.8.2 tls "floatformat_ieee_single_little",
94 1.1.1.1.8.2 tls floatformat_always_valid,
95 1.1.1.1.8.2 tls NULL
96 1.1.1.1.8.2 tls };
97 1.1.1.1.8.2 tls const struct floatformat floatformat_ieee_double_big =
98 1.1.1.1.8.2 tls {
99 1.1.1.1.8.2 tls floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52,
100 1.1.1.1.8.2 tls floatformat_intbit_no,
101 1.1.1.1.8.2 tls "floatformat_ieee_double_big",
102 1.1.1.1.8.2 tls floatformat_always_valid,
103 1.1.1.1.8.2 tls NULL
104 1.1.1.1.8.2 tls };
105 1.1.1.1.8.2 tls const struct floatformat floatformat_ieee_double_little =
106 1.1.1.1.8.2 tls {
107 1.1.1.1.8.2 tls floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52,
108 1.1.1.1.8.2 tls floatformat_intbit_no,
109 1.1.1.1.8.2 tls "floatformat_ieee_double_little",
110 1.1.1.1.8.2 tls floatformat_always_valid,
111 1.1.1.1.8.2 tls NULL
112 1.1.1.1.8.2 tls };
113 1.1.1.1.8.2 tls
114 1.1.1.1.8.2 tls /* floatformat for IEEE double, little endian byte order, with big endian word
115 1.1.1.1.8.2 tls ordering, as on the ARM. */
116 1.1.1.1.8.2 tls
117 1.1.1.1.8.2 tls const struct floatformat floatformat_ieee_double_littlebyte_bigword =
118 1.1.1.1.8.2 tls {
119 1.1.1.1.8.2 tls floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52,
120 1.1.1.1.8.2 tls floatformat_intbit_no,
121 1.1.1.1.8.2 tls "floatformat_ieee_double_littlebyte_bigword",
122 1.1.1.1.8.2 tls floatformat_always_valid,
123 1.1.1.1.8.2 tls NULL
124 1.1.1.1.8.2 tls };
125 1.1.1.1.8.2 tls
126 1.1.1.1.8.2 tls /* floatformat for VAX. Not quite IEEE, but close enough. */
127 1.1.1.1.8.2 tls
128 1.1.1.1.8.2 tls const struct floatformat floatformat_vax_f =
129 1.1.1.1.8.2 tls {
130 1.1.1.1.8.2 tls floatformat_vax, 32, 0, 1, 8, 129, 0, 9, 23,
131 1.1.1.1.8.2 tls floatformat_intbit_no,
132 1.1.1.1.8.2 tls "floatformat_vax_f",
133 1.1.1.1.8.2 tls floatformat_always_valid,
134 1.1.1.1.8.2 tls NULL
135 1.1.1.1.8.2 tls };
136 1.1.1.1.8.2 tls const struct floatformat floatformat_vax_d =
137 1.1.1.1.8.2 tls {
138 1.1.1.1.8.2 tls floatformat_vax, 64, 0, 1, 8, 129, 0, 9, 55,
139 1.1.1.1.8.2 tls floatformat_intbit_no,
140 1.1.1.1.8.2 tls "floatformat_vax_d",
141 1.1.1.1.8.2 tls floatformat_always_valid,
142 1.1.1.1.8.2 tls NULL
143 1.1.1.1.8.2 tls };
144 1.1.1.1.8.2 tls const struct floatformat floatformat_vax_g =
145 1.1.1.1.8.2 tls {
146 1.1.1.1.8.2 tls floatformat_vax, 64, 0, 1, 11, 1025, 0, 12, 52,
147 1.1.1.1.8.2 tls floatformat_intbit_no,
148 1.1.1.1.8.2 tls "floatformat_vax_g",
149 1.1.1.1.8.2 tls floatformat_always_valid,
150 1.1.1.1.8.2 tls NULL
151 1.1.1.1.8.2 tls };
152 1.1.1.1.8.2 tls
153 1.1.1.1.8.2 tls static int floatformat_i387_ext_is_valid (const struct floatformat *fmt,
154 1.1.1.1.8.2 tls const void *from);
155 1.1.1.1.8.2 tls
156 1.1.1.1.8.2 tls static int
157 1.1.1.1.8.2 tls floatformat_i387_ext_is_valid (const struct floatformat *fmt, const void *from)
158 1.1.1.1.8.2 tls {
159 1.1.1.1.8.2 tls /* In the i387 double-extended format, if the exponent is all ones,
160 1.1.1.1.8.2 tls then the integer bit must be set. If the exponent is neither 0
161 1.1.1.1.8.2 tls nor ~0, the intbit must also be set. Only if the exponent is
162 1.1.1.1.8.2 tls zero can it be zero, and then it must be zero. */
163 1.1.1.1.8.2 tls unsigned long exponent, int_bit;
164 1.1.1.1.8.2 tls const unsigned char *ufrom = (const unsigned char *) from;
165 1.1.1.1.8.2 tls
166 1.1.1.1.8.2 tls exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
167 1.1.1.1.8.2 tls fmt->exp_start, fmt->exp_len);
168 1.1.1.1.8.2 tls int_bit = get_field (ufrom, fmt->byteorder, fmt->totalsize,
169 1.1.1.1.8.2 tls fmt->man_start, 1);
170 1.1.1.1.8.2 tls
171 1.1.1.1.8.2 tls if ((exponent == 0) != (int_bit == 0))
172 1.1.1.1.8.2 tls return 0;
173 1.1.1.1.8.2 tls else
174 1.1.1.1.8.2 tls return 1;
175 1.1.1.1.8.2 tls }
176 1.1.1.1.8.2 tls
177 1.1.1.1.8.2 tls const struct floatformat floatformat_i387_ext =
178 1.1.1.1.8.2 tls {
179 1.1.1.1.8.2 tls floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
180 1.1.1.1.8.2 tls floatformat_intbit_yes,
181 1.1.1.1.8.2 tls "floatformat_i387_ext",
182 1.1.1.1.8.2 tls floatformat_i387_ext_is_valid,
183 1.1.1.1.8.2 tls NULL
184 1.1.1.1.8.2 tls };
185 1.1.1.1.8.2 tls const struct floatformat floatformat_m68881_ext =
186 1.1.1.1.8.2 tls {
187 1.1.1.1.8.2 tls /* Note that the bits from 16 to 31 are unused. */
188 1.1.1.1.8.2 tls floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64,
189 1.1.1.1.8.2 tls floatformat_intbit_yes,
190 1.1.1.1.8.2 tls "floatformat_m68881_ext",
191 1.1.1.1.8.2 tls floatformat_always_valid,
192 1.1.1.1.8.2 tls NULL
193 1.1.1.1.8.2 tls };
194 1.1.1.1.8.2 tls const struct floatformat floatformat_i960_ext =
195 1.1.1.1.8.2 tls {
196 1.1.1.1.8.2 tls /* Note that the bits from 0 to 15 are unused. */
197 1.1.1.1.8.2 tls floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64,
198 1.1.1.1.8.2 tls floatformat_intbit_yes,
199 1.1.1.1.8.2 tls "floatformat_i960_ext",
200 1.1.1.1.8.2 tls floatformat_always_valid,
201 1.1.1.1.8.2 tls NULL
202 1.1.1.1.8.2 tls };
203 1.1.1.1.8.2 tls const struct floatformat floatformat_m88110_ext =
204 1.1.1.1.8.2 tls {
205 1.1.1.1.8.2 tls floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
206 1.1.1.1.8.2 tls floatformat_intbit_yes,
207 1.1.1.1.8.2 tls "floatformat_m88110_ext",
208 1.1.1.1.8.2 tls floatformat_always_valid,
209 1.1.1.1.8.2 tls NULL
210 1.1.1.1.8.2 tls };
211 1.1.1.1.8.2 tls const struct floatformat floatformat_m88110_harris_ext =
212 1.1.1.1.8.2 tls {
213 1.1.1.1.8.2 tls /* Harris uses raw format 128 bytes long, but the number is just an ieee
214 1.1.1.1.8.2 tls double, and the last 64 bits are wasted. */
215 1.1.1.1.8.2 tls floatformat_big,128, 0, 1, 11, 0x3ff, 0x7ff, 12, 52,
216 1.1.1.1.8.2 tls floatformat_intbit_no,
217 1.1.1.1.8.2 tls "floatformat_m88110_ext_harris",
218 1.1.1.1.8.2 tls floatformat_always_valid,
219 1.1.1.1.8.2 tls NULL
220 1.1.1.1.8.2 tls };
221 1.1.1.1.8.2 tls const struct floatformat floatformat_arm_ext_big =
222 1.1.1.1.8.2 tls {
223 1.1.1.1.8.2 tls /* Bits 1 to 16 are unused. */
224 1.1.1.1.8.2 tls floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
225 1.1.1.1.8.2 tls floatformat_intbit_yes,
226 1.1.1.1.8.2 tls "floatformat_arm_ext_big",
227 1.1.1.1.8.2 tls floatformat_always_valid,
228 1.1.1.1.8.2 tls NULL
229 1.1.1.1.8.2 tls };
230 1.1.1.1.8.2 tls const struct floatformat floatformat_arm_ext_littlebyte_bigword =
231 1.1.1.1.8.2 tls {
232 1.1.1.1.8.2 tls /* Bits 1 to 16 are unused. */
233 1.1.1.1.8.2 tls floatformat_littlebyte_bigword, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
234 1.1.1.1.8.2 tls floatformat_intbit_yes,
235 1.1.1.1.8.2 tls "floatformat_arm_ext_littlebyte_bigword",
236 1.1.1.1.8.2 tls floatformat_always_valid,
237 1.1.1.1.8.2 tls NULL
238 1.1.1.1.8.2 tls };
239 1.1.1.1.8.2 tls const struct floatformat floatformat_ia64_spill_big =
240 1.1.1.1.8.2 tls {
241 1.1.1.1.8.2 tls floatformat_big, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
242 1.1.1.1.8.2 tls floatformat_intbit_yes,
243 1.1.1.1.8.2 tls "floatformat_ia64_spill_big",
244 1.1.1.1.8.2 tls floatformat_always_valid,
245 1.1.1.1.8.2 tls NULL
246 1.1.1.1.8.2 tls };
247 1.1.1.1.8.2 tls const struct floatformat floatformat_ia64_spill_little =
248 1.1.1.1.8.2 tls {
249 1.1.1.1.8.2 tls floatformat_little, 128, 0, 1, 17, 65535, 0x1ffff, 18, 64,
250 1.1.1.1.8.2 tls floatformat_intbit_yes,
251 1.1.1.1.8.2 tls "floatformat_ia64_spill_little",
252 1.1.1.1.8.2 tls floatformat_always_valid,
253 1.1.1.1.8.2 tls NULL
254 1.1.1.1.8.2 tls };
255 1.1.1.1.8.2 tls const struct floatformat floatformat_ia64_quad_big =
256 1.1.1.1.8.2 tls {
257 1.1.1.1.8.2 tls floatformat_big, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
258 1.1.1.1.8.2 tls floatformat_intbit_no,
259 1.1.1.1.8.2 tls "floatformat_ia64_quad_big",
260 1.1.1.1.8.2 tls floatformat_always_valid,
261 1.1.1.1.8.2 tls NULL
262 1.1.1.1.8.2 tls };
263 1.1.1.1.8.2 tls const struct floatformat floatformat_ia64_quad_little =
264 1.1.1.1.8.2 tls {
265 1.1.1.1.8.2 tls floatformat_little, 128, 0, 1, 15, 16383, 0x7fff, 16, 112,
266 1.1.1.1.8.2 tls floatformat_intbit_no,
267 1.1.1.1.8.2 tls "floatformat_ia64_quad_little",
268 1.1.1.1.8.2 tls floatformat_always_valid,
269 1.1.1.1.8.2 tls NULL
270 1.1.1.1.8.2 tls };
271 1.1.1.1.8.2 tls
272 1.1.1.1.8.2 tls static int
273 1.1.1.1.8.2 tls floatformat_ibm_long_double_is_valid (const struct floatformat *fmt,
274 1.1.1.1.8.2 tls const void *from)
275 1.1.1.1.8.2 tls {
276 1.1.1.1.8.2 tls const unsigned char *ufrom = (const unsigned char *) from;
277 1.1.1.1.8.2 tls const struct floatformat *hfmt = fmt->split_half;
278 1.1.1.1.8.2 tls long top_exp, bot_exp;
279 1.1.1.1.8.2 tls int top_nan = 0;
280 1.1.1.1.8.2 tls
281 1.1.1.1.8.2 tls top_exp = get_field (ufrom, hfmt->byteorder, hfmt->totalsize,
282 1.1.1.1.8.2 tls hfmt->exp_start, hfmt->exp_len);
283 1.1.1.1.8.2 tls bot_exp = get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize,
284 1.1.1.1.8.2 tls hfmt->exp_start, hfmt->exp_len);
285 1.1.1.1.8.2 tls
286 1.1.1.1.8.2 tls if ((unsigned long) top_exp == hfmt->exp_nan)
287 1.1.1.1.8.2 tls top_nan = mant_bits_set (hfmt, ufrom);
288 1.1.1.1.8.2 tls
289 1.1.1.1.8.2 tls /* A NaN is valid with any low part. */
290 1.1.1.1.8.2 tls if (top_nan)
291 1.1.1.1.8.2 tls return 1;
292 1.1.1.1.8.2 tls
293 1.1.1.1.8.2 tls /* An infinity, zero or denormal requires low part 0 (positive or
294 1.1.1.1.8.2 tls negative). */
295 1.1.1.1.8.2 tls if ((unsigned long) top_exp == hfmt->exp_nan || top_exp == 0)
296 1.1.1.1.8.2 tls {
297 1.1.1.1.8.2 tls if (bot_exp != 0)
298 1.1.1.1.8.2 tls return 0;
299 1.1.1.1.8.2 tls
300 1.1.1.1.8.2 tls return !mant_bits_set (hfmt, ufrom + 8);
301 1.1.1.1.8.2 tls }
302 1.1.1.1.8.2 tls
303 1.1.1.1.8.2 tls /* The top part is now a finite normal value. The long double value
304 1.1.1.1.8.2 tls is the sum of the two parts, and the top part must equal the
305 1.1.1.1.8.2 tls result of rounding the long double value to nearest double. Thus
306 1.1.1.1.8.2 tls the bottom part must be <= 0.5ulp of the top part in absolute
307 1.1.1.1.8.2 tls value, and if it is < 0.5ulp then the long double is definitely
308 1.1.1.1.8.2 tls valid. */
309 1.1.1.1.8.2 tls if (bot_exp < top_exp - 53)
310 1.1.1.1.8.2 tls return 1;
311 1.1.1.1.8.2 tls if (bot_exp > top_exp - 53 && bot_exp != 0)
312 1.1.1.1.8.2 tls return 0;
313 1.1.1.1.8.2 tls if (bot_exp == 0)
314 1.1.1.1.8.2 tls {
315 1.1.1.1.8.2 tls /* The bottom part is 0 or denormal. Determine which, and if
316 1.1.1.1.8.2 tls denormal the first two set bits. */
317 1.1.1.1.8.2 tls int first_bit = -1, second_bit = -1, cur_bit;
318 1.1.1.1.8.2 tls for (cur_bit = 0; (unsigned int) cur_bit < hfmt->man_len; cur_bit++)
319 1.1.1.1.8.2 tls if (get_field (ufrom + 8, hfmt->byteorder, hfmt->totalsize,
320 1.1.1.1.8.2 tls hfmt->man_start + cur_bit, 1))
321 1.1.1.1.8.2 tls {
322 1.1.1.1.8.2 tls if (first_bit == -1)
323 1.1.1.1.8.2 tls first_bit = cur_bit;
324 1.1.1.1.8.2 tls else
325 1.1.1.1.8.2 tls {
326 1.1.1.1.8.2 tls second_bit = cur_bit;
327 1.1.1.1.8.2 tls break;
328 1.1.1.1.8.2 tls }
329 1.1.1.1.8.2 tls }
330 1.1.1.1.8.2 tls /* Bottom part 0 is OK. */
331 1.1.1.1.8.2 tls if (first_bit == -1)
332 1.1.1.1.8.2 tls return 1;
333 1.1.1.1.8.2 tls /* The real exponent of the bottom part is -first_bit. */
334 1.1.1.1.8.2 tls if (-first_bit < top_exp - 53)
335 1.1.1.1.8.2 tls return 1;
336 1.1.1.1.8.2 tls if (-first_bit > top_exp - 53)
337 1.1.1.1.8.2 tls return 0;
338 1.1.1.1.8.2 tls /* The bottom part is at least 0.5ulp of the top part. For this
339 1.1.1.1.8.2 tls to be OK, the bottom part must be exactly 0.5ulp (i.e. no
340 1.1.1.1.8.2 tls more bits set) and the top part must have last bit 0. */
341 1.1.1.1.8.2 tls if (second_bit != -1)
342 1.1.1.1.8.2 tls return 0;
343 1.1.1.1.8.2 tls return !get_field (ufrom, hfmt->byteorder, hfmt->totalsize,
344 1.1.1.1.8.2 tls hfmt->man_start + hfmt->man_len - 1, 1);
345 1.1.1.1.8.2 tls }
346 1.1.1.1.8.2 tls else
347 1.1.1.1.8.2 tls {
348 1.1.1.1.8.2 tls /* The bottom part is at least 0.5ulp of the top part. For this
349 1.1.1.1.8.2 tls to be OK, it must be exactly 0.5ulp (i.e. no explicit bits
350 1.1.1.1.8.2 tls set) and the top part must have last bit 0. */
351 1.1.1.1.8.2 tls if (get_field (ufrom, hfmt->byteorder, hfmt->totalsize,
352 1.1.1.1.8.2 tls hfmt->man_start + hfmt->man_len - 1, 1))
353 1.1.1.1.8.2 tls return 0;
354 1.1.1.1.8.2 tls return !mant_bits_set (hfmt, ufrom + 8);
355 1.1.1.1.8.2 tls }
356 1.1.1.1.8.2 tls }
357 1.1.1.1.8.2 tls
358 1.1.1.1.8.2 tls const struct floatformat floatformat_ibm_long_double =
359 1.1.1.1.8.2 tls {
360 1.1.1.1.8.2 tls floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52,
361 1.1.1.1.8.2 tls floatformat_intbit_no,
362 1.1.1.1.8.2 tls "floatformat_ibm_long_double",
363 1.1.1.1.8.2 tls floatformat_ibm_long_double_is_valid,
364 1.1.1.1.8.2 tls &floatformat_ieee_double_big
365 1.1.1.1.8.2 tls };
366 1.1.1.1.8.2 tls
367 1.1.1.1.8.2 tls
369 1.1.1.1.8.2 tls #ifndef min
370 1.1.1.1.8.2 tls #define min(a, b) ((a) < (b) ? (a) : (b))
371 1.1.1.1.8.2 tls #endif
372 1.1.1.1.8.2 tls
373 1.1.1.1.8.2 tls /* Return 1 if any bits are explicitly set in the mantissa of UFROM,
374 1.1.1.1.8.2 tls format FMT, 0 otherwise. */
375 1.1.1.1.8.2 tls static int
376 1.1.1.1.8.2 tls mant_bits_set (const struct floatformat *fmt, const unsigned char *ufrom)
377 1.1.1.1.8.2 tls {
378 1.1.1.1.8.2 tls unsigned int mant_bits, mant_off;
379 1.1.1.1.8.2 tls int mant_bits_left;
380 1.1.1.1.8.2 tls
381 1.1.1.1.8.2 tls mant_off = fmt->man_start;
382 1.1.1.1.8.2 tls mant_bits_left = fmt->man_len;
383 1.1.1.1.8.2 tls while (mant_bits_left > 0)
384 1.1.1.1.8.2 tls {
385 1.1.1.1.8.2 tls mant_bits = min (mant_bits_left, 32);
386 1.1.1.1.8.2 tls
387 1.1.1.1.8.2 tls if (get_field (ufrom, fmt->byteorder, fmt->totalsize,
388 1.1.1.1.8.2 tls mant_off, mant_bits) != 0)
389 1.1.1.1.8.2 tls return 1;
390 1.1.1.1.8.2 tls
391 1.1.1.1.8.2 tls mant_off += mant_bits;
392 1.1.1.1.8.2 tls mant_bits_left -= mant_bits;
393 1.1.1.1.8.2 tls }
394 1.1.1.1.8.2 tls return 0;
395 1.1.1.1.8.2 tls }
396 1.1.1.1.8.2 tls
397 1.1.1.1.8.2 tls /* Extract a field which starts at START and is LEN bits long. DATA and
398 1.1.1.1.8.2 tls TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
399 1.1.1.1.8.2 tls static unsigned long
400 1.1.1.1.8.2 tls get_field (const unsigned char *data, enum floatformat_byteorders order,
401 1.1.1.1.8.2 tls unsigned int total_len, unsigned int start, unsigned int len)
402 1.1.1.1.8.2 tls {
403 1.1.1.1.8.2 tls unsigned long result = 0;
404 1.1.1.1.8.2 tls unsigned int cur_byte;
405 1.1.1.1.8.2 tls int lo_bit, hi_bit, cur_bitshift = 0;
406 1.1.1.1.8.2 tls int nextbyte = (order == floatformat_little) ? 1 : -1;
407 1.1.1.1.8.2 tls
408 1.1.1.1.8.2 tls /* Start is in big-endian bit order! Fix that first. */
409 1.1.1.1.8.2 tls start = total_len - (start + len);
410 1.1.1.1.8.2 tls
411 1.1.1.1.8.2 tls /* Start at the least significant part of the field. */
412 1.1.1.1.8.2 tls if (order == floatformat_little)
413 1.1.1.1.8.2 tls cur_byte = start / FLOATFORMAT_CHAR_BIT;
414 1.1.1.1.8.2 tls else
415 1.1.1.1.8.2 tls cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
416 1.1.1.1.8.2 tls
417 1.1.1.1.8.2 tls lo_bit = start % FLOATFORMAT_CHAR_BIT;
418 1.1.1.1.8.2 tls hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
419 1.1.1.1.8.2 tls
420 1.1.1.1.8.2 tls do
421 1.1.1.1.8.2 tls {
422 1.1.1.1.8.2 tls unsigned int shifted = *(data + cur_byte) >> lo_bit;
423 1.1.1.1.8.2 tls unsigned int bits = hi_bit - lo_bit;
424 1.1.1.1.8.2 tls unsigned int mask = (1 << bits) - 1;
425 1.1.1.1.8.2 tls result |= (shifted & mask) << cur_bitshift;
426 1.1.1.1.8.2 tls len -= bits;
427 1.1.1.1.8.2 tls cur_bitshift += bits;
428 1.1.1.1.8.2 tls cur_byte += nextbyte;
429 1.1.1.1.8.2 tls lo_bit = 0;
430 1.1.1.1.8.2 tls hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
431 1.1.1.1.8.2 tls }
432 1.1.1.1.8.2 tls while (len != 0);
433 1.1.1.1.8.2 tls
434 1.1.1.1.8.2 tls return result;
435 1.1.1.1.8.2 tls }
436 1.1.1.1.8.2 tls
437 1.1.1.1.8.2 tls /* Convert from FMT to a double.
438 1.1.1.1.8.2 tls FROM is the address of the extended float.
439 1.1.1.1.8.2 tls Store the double in *TO. */
440 1.1.1.1.8.2 tls
441 1.1.1.1.8.2 tls void
442 1.1.1.1.8.2 tls floatformat_to_double (const struct floatformat *fmt,
443 1.1.1.1.8.2 tls const void *from, double *to)
444 1.1.1.1.8.2 tls {
445 1.1.1.1.8.2 tls const unsigned char *ufrom = (const unsigned char *) from;
446 1.1.1.1.8.2 tls double dto;
447 1.1.1.1.8.2 tls long exponent;
448 1.1.1.1.8.2 tls unsigned long mant;
449 1.1.1.1.8.2 tls unsigned int mant_bits, mant_off;
450 1.1.1.1.8.2 tls int mant_bits_left;
451 1.1.1.1.8.2 tls int special_exponent; /* It's a NaN, denorm or zero */
452 1.1.1.1.8.2 tls
453 1.1.1.1.8.2 tls /* Split values are not handled specially, since the top half has
454 1.1.1.1.8.2 tls the correctly rounded double value (in the only supported case of
455 1.1.1.1.8.2 tls split values). */
456 1.1.1.1.8.2 tls
457 1.1.1.1.8.2 tls exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
458 1.1.1.1.8.2 tls fmt->exp_start, fmt->exp_len);
459 1.1.1.1.8.2 tls
460 1.1.1.1.8.2 tls /* If the exponent indicates a NaN, we don't have information to
461 1.1.1.1.8.2 tls decide what to do. So we handle it like IEEE, except that we
462 1.1.1.1.8.2 tls don't try to preserve the type of NaN. FIXME. */
463 1.1.1.1.8.2 tls if ((unsigned long) exponent == fmt->exp_nan)
464 1.1.1.1.8.2 tls {
465 1.1.1.1.8.2 tls int nan = mant_bits_set (fmt, ufrom);
466 1.1.1.1.8.2 tls
467 1.1.1.1.8.2 tls /* On certain systems (such as GNU/Linux), the use of the
468 1.1.1.1.8.2 tls INFINITY macro below may generate a warning that can not be
469 1.1.1.1.8.2 tls silenced due to a bug in GCC (PR preprocessor/11931). The
470 1.1.1.1.8.2 tls preprocessor fails to recognise the __extension__ keyword in
471 1.1.1.1.8.2 tls conjunction with the GNU/C99 extension for hexadecimal
472 1.1.1.1.8.2 tls floating point constants and will issue a warning when
473 1.1.1.1.8.2 tls compiling with -pedantic. */
474 1.1.1.1.8.2 tls if (nan)
475 1.1.1.1.8.2 tls dto = NAN;
476 1.1.1.1.8.2 tls else
477 1.1.1.1.8.2 tls #ifdef __vax__
478 1.1.1.1.8.2 tls dto = HUGE_VAL;
479 1.1.1.1.8.2 tls #else
480 1.1.1.1.8.2 tls dto = INFINITY;
481 1.1.1.1.8.2 tls #endif
482 1.1.1.1.8.2 tls
483 1.1.1.1.8.2 tls if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
484 1.1.1.1.8.2 tls dto = -dto;
485 1.1.1.1.8.2 tls
486 1.1.1.1.8.2 tls *to = dto;
487 1.1.1.1.8.2 tls
488 1.1.1.1.8.2 tls return;
489 1.1.1.1.8.2 tls }
490 1.1.1.1.8.2 tls
491 1.1.1.1.8.2 tls mant_bits_left = fmt->man_len;
492 1.1.1.1.8.2 tls mant_off = fmt->man_start;
493 1.1.1.1.8.2 tls dto = 0.0;
494 1.1.1.1.8.2 tls
495 1.1.1.1.8.2 tls special_exponent = exponent == 0 || (unsigned long) exponent == fmt->exp_nan;
496 1.1.1.1.8.2 tls
497 1.1.1.1.8.2 tls /* Don't bias zero's, denorms or NaNs. */
498 1.1.1.1.8.2 tls if (!special_exponent)
499 1.1.1.1.8.2 tls exponent -= fmt->exp_bias;
500 1.1.1.1.8.2 tls
501 1.1.1.1.8.2 tls /* Build the result algebraically. Might go infinite, underflow, etc;
502 1.1.1.1.8.2 tls who cares. */
503 1.1.1.1.8.2 tls
504 1.1.1.1.8.2 tls /* If this format uses a hidden bit, explicitly add it in now. Otherwise,
505 1.1.1.1.8.2 tls increment the exponent by one to account for the integer bit. */
506 1.1.1.1.8.2 tls
507 1.1.1.1.8.2 tls if (!special_exponent)
508 1.1.1.1.8.2 tls {
509 1.1.1.1.8.2 tls if (fmt->intbit == floatformat_intbit_no)
510 1.1.1.1.8.2 tls dto = ldexp (1.0, exponent);
511 1.1.1.1.8.2 tls else
512 1.1.1.1.8.2 tls exponent++;
513 1.1.1.1.8.2 tls }
514 1.1.1.1.8.2 tls
515 1.1.1.1.8.2 tls while (mant_bits_left > 0)
516 1.1.1.1.8.2 tls {
517 1.1.1.1.8.2 tls mant_bits = min (mant_bits_left, 32);
518 1.1.1.1.8.2 tls
519 1.1.1.1.8.2 tls mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
520 1.1.1.1.8.2 tls mant_off, mant_bits);
521 1.1.1.1.8.2 tls
522 1.1.1.1.8.2 tls /* Handle denormalized numbers. FIXME: What should we do for
523 1.1.1.1.8.2 tls non-IEEE formats? */
524 1.1.1.1.8.2 tls if (special_exponent && exponent == 0 && mant != 0)
525 1.1.1.1.8.2 tls dto += ldexp ((double)mant,
526 1.1.1.1.8.2 tls (- fmt->exp_bias
527 1.1.1.1.8.2 tls - mant_bits
528 1.1.1.1.8.2 tls - (mant_off - fmt->man_start)
529 1.1.1.1.8.2 tls + 1));
530 1.1.1.1.8.2 tls else
531 1.1.1.1.8.2 tls dto += ldexp ((double)mant, exponent - mant_bits);
532 1.1.1.1.8.2 tls if (exponent != 0)
533 1.1.1.1.8.2 tls exponent -= mant_bits;
534 1.1.1.1.8.2 tls mant_off += mant_bits;
535 1.1.1.1.8.2 tls mant_bits_left -= mant_bits;
536 1.1.1.1.8.2 tls }
537 1.1.1.1.8.2 tls
538 1.1.1.1.8.2 tls /* Negate it if negative. */
539 1.1.1.1.8.2 tls if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
540 1.1.1.1.8.2 tls dto = -dto;
541 1.1.1.1.8.2 tls *to = dto;
542 1.1.1.1.8.2 tls }
543 1.1.1.1.8.2 tls
544 1.1.1.1.8.2 tls static void put_field (unsigned char *, enum floatformat_byteorders,
546 1.1.1.1.8.2 tls unsigned int,
547 1.1.1.1.8.2 tls unsigned int,
548 1.1.1.1.8.2 tls unsigned int,
549 1.1.1.1.8.2 tls unsigned long);
550 1.1.1.1.8.2 tls
551 1.1.1.1.8.2 tls /* Set a field which starts at START and is LEN bits long. DATA and
552 1.1.1.1.8.2 tls TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
553 1.1.1.1.8.2 tls static void
554 1.1.1.1.8.2 tls put_field (unsigned char *data, enum floatformat_byteorders order,
555 1.1.1.1.8.2 tls unsigned int total_len, unsigned int start, unsigned int len,
556 1.1.1.1.8.2 tls unsigned long stuff_to_put)
557 1.1.1.1.8.2 tls {
558 1.1.1.1.8.2 tls unsigned int cur_byte;
559 1.1.1.1.8.2 tls int lo_bit, hi_bit;
560 1.1.1.1.8.2 tls int nextbyte = (order == floatformat_little) ? 1 : -1;
561 1.1.1.1.8.2 tls
562 1.1.1.1.8.2 tls /* Start is in big-endian bit order! Fix that first. */
563 1.1.1.1.8.2 tls start = total_len - (start + len);
564 1.1.1.1.8.2 tls
565 1.1.1.1.8.2 tls /* Start at the least significant part of the field. */
566 1.1.1.1.8.2 tls if (order == floatformat_little)
567 1.1.1.1.8.2 tls cur_byte = start / FLOATFORMAT_CHAR_BIT;
568 1.1.1.1.8.2 tls else
569 1.1.1.1.8.2 tls cur_byte = (total_len - start - 1) / FLOATFORMAT_CHAR_BIT;
570 1.1.1.1.8.2 tls
571 1.1.1.1.8.2 tls lo_bit = start % FLOATFORMAT_CHAR_BIT;
572 1.1.1.1.8.2 tls hi_bit = min (lo_bit + len, FLOATFORMAT_CHAR_BIT);
573 1.1.1.1.8.2 tls
574 1.1.1.1.8.2 tls do
575 1.1.1.1.8.2 tls {
576 1.1.1.1.8.2 tls unsigned char *byte_ptr = data + cur_byte;
577 1.1.1.1.8.2 tls unsigned int bits = hi_bit - lo_bit;
578 1.1.1.1.8.2 tls unsigned int mask = ((1 << bits) - 1) << lo_bit;
579 1.1.1.1.8.2 tls *byte_ptr = (*byte_ptr & ~mask) | ((stuff_to_put << lo_bit) & mask);
580 1.1.1.1.8.2 tls stuff_to_put >>= bits;
581 1.1.1.1.8.2 tls len -= bits;
582 1.1.1.1.8.2 tls cur_byte += nextbyte;
583 1.1.1.1.8.2 tls lo_bit = 0;
584 1.1.1.1.8.2 tls hi_bit = min (len, FLOATFORMAT_CHAR_BIT);
585 1.1.1.1.8.2 tls }
586 1.1.1.1.8.2 tls while (len != 0);
587 1.1.1.1.8.2 tls }
588 1.1.1.1.8.2 tls
589 1.1.1.1.8.2 tls /* The converse: convert the double *FROM to an extended float
590 1.1.1.1.8.2 tls and store where TO points. Neither FROM nor TO have any alignment
591 1.1.1.1.8.2 tls restrictions. */
592 1.1.1.1.8.2 tls
593 1.1.1.1.8.2 tls void
594 1.1.1.1.8.2 tls floatformat_from_double (const struct floatformat *fmt,
595 1.1.1.1.8.2 tls const double *from, void *to)
596 1.1.1.1.8.2 tls {
597 1.1.1.1.8.2 tls double dfrom;
598 1.1.1.1.8.2 tls int exponent;
599 1.1.1.1.8.2 tls double mant;
600 1.1.1.1.8.2 tls unsigned int mant_bits, mant_off;
601 1.1.1.1.8.2 tls int mant_bits_left;
602 1.1.1.1.8.2 tls unsigned char *uto = (unsigned char *) to;
603 1.1.1.1.8.2 tls
604 1.1.1.1.8.2 tls dfrom = *from;
605 1.1.1.1.8.2 tls memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
606 1.1.1.1.8.2 tls
607 1.1.1.1.8.2 tls /* Split values are not handled specially, since a bottom half of
608 1.1.1.1.8.2 tls zero is correct for any value representable as double (in the
609 1.1.1.1.8.2 tls only supported case of split values). */
610 1.1.1.1.8.2 tls
611 1.1.1.1.8.2 tls /* If negative, set the sign bit. */
612 1.1.1.1.8.2 tls if (dfrom < 0)
613 1.1.1.1.8.2 tls {
614 1.1.1.1.8.2 tls put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
615 1.1.1.1.8.2 tls dfrom = -dfrom;
616 1.1.1.1.8.2 tls }
617 1.1.1.1.8.2 tls
618 1.1.1.1.8.2 tls if (dfrom == 0)
619 1.1.1.1.8.2 tls {
620 1.1.1.1.8.2 tls /* 0.0. */
621 1.1.1.1.8.2 tls return;
622 1.1.1.1.8.2 tls }
623 1.1.1.1.8.2 tls
624 1.1.1.1.8.2 tls if (dfrom != dfrom)
625 1.1.1.1.8.2 tls {
626 1.1.1.1.8.2 tls /* NaN. */
627 1.1.1.1.8.2 tls put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
628 1.1.1.1.8.2 tls fmt->exp_len, fmt->exp_nan);
629 1.1.1.1.8.2 tls /* Be sure it's not infinity, but NaN value is irrelevant. */
630 1.1.1.1.8.2 tls put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
631 1.1.1.1.8.2 tls 32, 1);
632 1.1.1.1.8.2 tls return;
633 1.1.1.1.8.2 tls }
634 1.1.1.1.8.2 tls
635 1.1.1.1.8.2 tls if (dfrom + dfrom == dfrom)
636 1.1.1.1.8.2 tls {
637 1.1.1.1.8.2 tls /* This can only happen for an infinite value (or zero, which we
638 1.1.1.1.8.2 tls already handled above). */
639 1.1.1.1.8.2 tls put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
640 1.1.1.1.8.2 tls fmt->exp_len, fmt->exp_nan);
641 1.1.1.1.8.2 tls return;
642 1.1.1.1.8.2 tls }
643 1.1.1.1.8.2 tls
644 1.1.1.1.8.2 tls mant = frexp (dfrom, &exponent);
645 1.1.1.1.8.2 tls if (exponent + fmt->exp_bias - 1 > 0)
646 1.1.1.1.8.2 tls put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
647 1.1.1.1.8.2 tls fmt->exp_len, exponent + fmt->exp_bias - 1);
648 1.1.1.1.8.2 tls else
649 1.1.1.1.8.2 tls {
650 1.1.1.1.8.2 tls /* Handle a denormalized number. FIXME: What should we do for
651 1.1.1.1.8.2 tls non-IEEE formats? */
652 1.1.1.1.8.2 tls put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
653 1.1.1.1.8.2 tls fmt->exp_len, 0);
654 1.1.1.1.8.2 tls mant = ldexp (mant, exponent + fmt->exp_bias - 1);
655 1.1.1.1.8.2 tls }
656 1.1.1.1.8.2 tls
657 1.1.1.1.8.2 tls mant_bits_left = fmt->man_len;
658 1.1.1.1.8.2 tls mant_off = fmt->man_start;
659 1.1.1.1.8.2 tls while (mant_bits_left > 0)
660 1.1.1.1.8.2 tls {
661 1.1.1.1.8.2 tls unsigned long mant_long;
662 1.1.1.1.8.2 tls mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
663 1.1.1.1.8.2 tls
664 1.1.1.1.8.2 tls mant *= 4294967296.0;
665 1.1.1.1.8.2 tls mant_long = (unsigned long)mant;
666 1.1.1.1.8.2 tls mant -= mant_long;
667 1.1.1.1.8.2 tls
668 1.1.1.1.8.2 tls /* If the integer bit is implicit, and we are not creating a
669 1.1.1.1.8.2 tls denormalized number, then we need to discard it. */
670 1.1.1.1.8.2 tls if ((unsigned int) mant_bits_left == fmt->man_len
671 1.1.1.1.8.2 tls && fmt->intbit == floatformat_intbit_no
672 1.1.1.1.8.2 tls && exponent + fmt->exp_bias - 1 > 0)
673 1.1.1.1.8.2 tls {
674 1.1.1.1.8.2 tls mant_long &= 0x7fffffff;
675 1.1.1.1.8.2 tls mant_bits -= 1;
676 1.1.1.1.8.2 tls }
677 1.1.1.1.8.2 tls else if (mant_bits < 32)
678 1.1.1.1.8.2 tls {
679 1.1.1.1.8.2 tls /* The bits we want are in the most significant MANT_BITS bits of
680 1.1.1.1.8.2 tls mant_long. Move them to the least significant. */
681 1.1.1.1.8.2 tls mant_long >>= 32 - mant_bits;
682 1.1.1.1.8.2 tls }
683 1.1.1.1.8.2 tls
684 1.1.1.1.8.2 tls put_field (uto, fmt->byteorder, fmt->totalsize,
685 1.1.1.1.8.2 tls mant_off, mant_bits, mant_long);
686 1.1.1.1.8.2 tls mant_off += mant_bits;
687 1.1.1.1.8.2 tls mant_bits_left -= mant_bits;
688 1.1.1.1.8.2 tls }
689 1.1.1.1.8.2 tls }
690 1.1.1.1.8.2 tls
691 1.1.1.1.8.2 tls /* Return non-zero iff the data at FROM is a valid number in format FMT. */
692 1.1.1.1.8.2 tls
693 1.1.1.1.8.2 tls int
694 1.1.1.1.8.2 tls floatformat_is_valid (const struct floatformat *fmt, const void *from)
695 1.1.1.1.8.2 tls {
696 1.1.1.1.8.2 tls return fmt->is_valid (fmt, from);
697 1.1.1.1.8.2 tls }
698 1.1.1.1.8.2 tls
699 1.1.1.1.8.2 tls
700 1.1.1.1.8.2 tls #ifdef IEEE_DEBUG
701 1.1.1.1.8.2 tls
702 1.1.1.1.8.2 tls #include <stdio.h>
703 1.1.1.1.8.2 tls
704 1.1.1.1.8.2 tls /* This is to be run on a host which uses IEEE floating point. */
705 1.1.1.1.8.2 tls
706 1.1.1.1.8.2 tls void
707 1.1.1.1.8.2 tls ieee_test (double n)
708 1.1.1.1.8.2 tls {
709 1.1.1.1.8.2 tls double result;
710 1.1.1.1.8.2 tls
711 1.1.1.1.8.2 tls floatformat_to_double (&floatformat_ieee_double_little, &n, &result);
712 1.1.1.1.8.2 tls if ((n != result && (! isnan (n) || ! isnan (result)))
713 1.1.1.1.8.2 tls || (n < 0 && result >= 0)
714 1.1.1.1.8.2 tls || (n >= 0 && result < 0))
715 1.1.1.1.8.2 tls printf ("Differ(to): %.20g -> %.20g\n", n, result);
716 1.1.1.1.8.2 tls
717 1.1.1.1.8.2 tls floatformat_from_double (&floatformat_ieee_double_little, &n, &result);
718 1.1.1.1.8.2 tls if ((n != result && (! isnan (n) || ! isnan (result)))
719 1.1.1.1.8.2 tls || (n < 0 && result >= 0)
720 1.1.1.1.8.2 tls || (n >= 0 && result < 0))
721 1.1.1.1.8.2 tls printf ("Differ(from): %.20g -> %.20g\n", n, result);
722 1.1.1.1.8.2 tls
723 1.1.1.1.8.2 tls #if 0
724 1.1.1.1.8.2 tls {
725 1.1.1.1.8.2 tls char exten[16];
726 1.1.1.1.8.2 tls
727 1.1.1.1.8.2 tls floatformat_from_double (&floatformat_m68881_ext, &n, exten);
728 1.1.1.1.8.2 tls floatformat_to_double (&floatformat_m68881_ext, exten, &result);
729 1.1.1.1.8.2 tls if (n != result)
730 1.1.1.1.8.2 tls printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
731 1.1.1.1.8.2 tls }
732 1.1.1.1.8.2 tls #endif
733 1.1.1.1.8.2 tls
734 1.1.1.1.8.2 tls #if IEEE_DEBUG > 1
735 1.1.1.1.8.2 tls /* This is to be run on a host which uses 68881 format. */
736 1.1.1.1.8.2 tls {
737 1.1.1.1.8.2 tls long double ex = *(long double *)exten;
738 1.1.1.1.8.2 tls if (ex != n)
739 1.1.1.1.8.2 tls printf ("Differ(from vs. extended): %.20g\n", n);
740 1.1.1.1.8.2 tls }
741 1.1.1.1.8.2 tls #endif
742 1.1.1.1.8.2 tls }
743 1.1.1.1.8.2 tls
744 1.1.1.1.8.2 tls int
745 1.1.1.1.8.2 tls main (void)
746 1.1.1.1.8.2 tls {
747 1.1.1.1.8.2 tls ieee_test (0.0);
748 1.1.1.1.8.2 tls ieee_test (0.5);
749 1.1.1.1.8.2 tls ieee_test (256.0);
750 1.1.1.1.8.2 tls ieee_test (0.12345);
751 1.1.1.1.8.2 tls ieee_test (234235.78907234);
752 1.1.1.1.8.2 tls ieee_test (-512.0);
753 1.1.1.1.8.2 tls ieee_test (-0.004321);
754 1.1.1.1.8.2 tls ieee_test (1.2E-70);
755 1.1.1.1.8.2 tls ieee_test (1.2E-316);
756 1.1.1.1.8.2 tls ieee_test (4.9406564584124654E-324);
757 1.1.1.1.8.2 tls ieee_test (- 4.9406564584124654E-324);
758 1.1.1.1.8.2 tls ieee_test (- 0.0);
759 1.1.1.1.8.2 tls ieee_test (- INFINITY);
760 1.1.1.1.8.2 tls ieee_test (- NAN);
761 1.1.1.1.8.2 tls ieee_test (INFINITY);
762 1.1.1.1.8.2 tls ieee_test (NAN);
763 1.1.1.1.8.2 tls return 0;
764 }
765 #endif
766