dp-bit.c revision 1.10 1 1.1 christos /* This is a software floating point library which can be used instead of
2 1.1 christos the floating point routines in libgcc1.c for targets without hardware
3 1.1 christos floating point. */
4 1.1 christos
5 1.10 christos /* Copyright (C) 1994-2023 Free Software Foundation, Inc.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos /* As a special exception, if you link this library with other files,
21 1.1 christos some of which are compiled with GCC, to produce an executable,
22 1.1 christos this library does not by itself cause the resulting executable
23 1.1 christos to be covered by the GNU General Public License.
24 1.1 christos This exception does not however invalidate any other reasons why
25 1.1 christos the executable file might be covered by the GNU General Public License. */
26 1.1 christos
27 1.1 christos /* This implements IEEE 754 format arithmetic, but does not provide a
28 1.1 christos mechanism for setting the rounding mode, or for generating or handling
29 1.1 christos exceptions.
30 1.1 christos
31 1.1 christos The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
32 1.1 christos Wilson, all of Cygnus Support. */
33 1.1 christos
34 1.1 christos /* The intended way to use this file is to make two copies, add `#define FLOAT'
35 1.1 christos to one copy, then compile both copies and add them to libgcc.a. */
36 1.1 christos
37 1.1 christos /* The following macros can be defined to change the behaviour of this file:
38 1.1 christos FLOAT: Implement a `float', aka SFmode, fp library. If this is not
39 1.1 christos defined, then this file implements a `double', aka DFmode, fp library.
40 1.1 christos FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
41 1.1 christos don't include float->double conversion which requires the double library.
42 1.1 christos This is useful only for machines which can't support doubles, e.g. some
43 1.1 christos 8-bit processors.
44 1.1 christos CMPtype: Specify the type that floating point compares should return.
45 1.1 christos This defaults to SItype, aka int.
46 1.1 christos US_SOFTWARE_GOFAST: This makes all entry points use the same names as the
47 1.1 christos US Software goFast library. If this is not defined, the entry points use
48 1.1 christos the same names as libgcc1.c.
49 1.1 christos _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
50 1.1 christos two integers to the FLO_union_type.
51 1.1 christos NO_NANS: Disable nan and infinity handling
52 1.1 christos SMALL_MACHINE: Useful when operations on QIs and HIs are faster
53 1.1 christos than on an SI */
54 1.1 christos
55 1.1 christos #ifndef SFtype
56 1.1 christos typedef SFtype __attribute__ ((mode (SF)));
57 1.1 christos #endif
58 1.1 christos #ifndef DFtype
59 1.1 christos typedef DFtype __attribute__ ((mode (DF)));
60 1.1 christos #endif
61 1.1 christos
62 1.1 christos #ifndef HItype
63 1.1 christos typedef int HItype __attribute__ ((mode (HI)));
64 1.1 christos #endif
65 1.1 christos #ifndef SItype
66 1.1 christos typedef int SItype __attribute__ ((mode (SI)));
67 1.1 christos #endif
68 1.1 christos #ifndef DItype
69 1.1 christos typedef int DItype __attribute__ ((mode (DI)));
70 1.1 christos #endif
71 1.1 christos
72 1.1 christos /* The type of the result of a fp compare */
73 1.1 christos #ifndef CMPtype
74 1.1 christos #define CMPtype SItype
75 1.1 christos #endif
76 1.1 christos
77 1.1 christos #ifndef UHItype
78 1.1 christos typedef unsigned int UHItype __attribute__ ((mode (HI)));
79 1.1 christos #endif
80 1.1 christos #ifndef USItype
81 1.1 christos typedef unsigned int USItype __attribute__ ((mode (SI)));
82 1.1 christos #endif
83 1.1 christos #ifndef UDItype
84 1.1 christos typedef unsigned int UDItype __attribute__ ((mode (DI)));
85 1.1 christos #endif
86 1.1 christos
87 1.1 christos #define MAX_SI_INT ((SItype) ((unsigned) (~0)>>1))
88 1.1 christos #define MAX_USI_INT ((USItype) ~0)
89 1.1 christos
90 1.1 christos
91 1.1 christos #ifdef FLOAT_ONLY
92 1.1 christos #define NO_DI_MODE
93 1.1 christos #endif
94 1.1 christos
95 1.1 christos #ifdef FLOAT
96 1.1 christos # define NGARDS 7L
97 1.1 christos # define GARDROUND 0x3f
98 1.1 christos # define GARDMASK 0x7f
99 1.1 christos # define GARDMSB 0x40
100 1.1 christos # define EXPBITS 8
101 1.1 christos # define EXPBIAS 127
102 1.1 christos # define FRACBITS 23
103 1.1 christos # define EXPMAX (0xff)
104 1.1 christos # define QUIET_NAN 0x100000L
105 1.1 christos # define FRAC_NBITS 32
106 1.1 christos # define FRACHIGH 0x80000000L
107 1.1 christos # define FRACHIGH2 0xc0000000L
108 1.1 christos typedef USItype fractype;
109 1.1 christos typedef UHItype halffractype;
110 1.1 christos typedef SFtype FLO_type;
111 1.1 christos typedef SItype intfrac;
112 1.1 christos
113 1.1 christos #else
114 1.1 christos # define PREFIXFPDP dp
115 1.1 christos # define PREFIXSFDF df
116 1.1 christos # define NGARDS 8L
117 1.1 christos # define GARDROUND 0x7f
118 1.1 christos # define GARDMASK 0xff
119 1.1 christos # define GARDMSB 0x80
120 1.1 christos # define EXPBITS 11
121 1.1 christos # define EXPBIAS 1023
122 1.1 christos # define FRACBITS 52
123 1.1 christos # define EXPMAX (0x7ff)
124 1.1 christos # define QUIET_NAN 0x8000000000000LL
125 1.1 christos # define FRAC_NBITS 64
126 1.1 christos # define FRACHIGH 0x8000000000000000LL
127 1.1 christos # define FRACHIGH2 0xc000000000000000LL
128 1.1 christos typedef UDItype fractype;
129 1.1 christos typedef USItype halffractype;
130 1.1 christos typedef DFtype FLO_type;
131 1.1 christos typedef DItype intfrac;
132 1.1 christos #endif
133 1.1 christos
134 1.1 christos #ifdef US_SOFTWARE_GOFAST
135 1.1 christos # ifdef FLOAT
136 1.1 christos # define add fpadd
137 1.1 christos # define sub fpsub
138 1.1 christos # define multiply fpmul
139 1.1 christos # define divide fpdiv
140 1.1 christos # define compare fpcmp
141 1.1 christos # define si_to_float sitofp
142 1.1 christos # define float_to_si fptosi
143 1.1 christos # define float_to_usi fptoui
144 1.1 christos # define negate __negsf2
145 1.1 christos # define sf_to_df fptodp
146 1.1 christos # define dptofp dptofp
147 1.1 christos #else
148 1.1 christos # define add dpadd
149 1.1 christos # define sub dpsub
150 1.1 christos # define multiply dpmul
151 1.1 christos # define divide dpdiv
152 1.1 christos # define compare dpcmp
153 1.1 christos # define si_to_float litodp
154 1.1 christos # define float_to_si dptoli
155 1.1 christos # define float_to_usi dptoul
156 1.1 christos # define negate __negdf2
157 1.1 christos # define df_to_sf dptofp
158 1.1 christos #endif
159 1.1 christos #else
160 1.1 christos # ifdef FLOAT
161 1.1 christos # define add __addsf3
162 1.1 christos # define sub __subsf3
163 1.1 christos # define multiply __mulsf3
164 1.1 christos # define divide __divsf3
165 1.1 christos # define compare __cmpsf2
166 1.1 christos # define _eq_f2 __eqsf2
167 1.1 christos # define _ne_f2 __nesf2
168 1.1 christos # define _gt_f2 __gtsf2
169 1.1 christos # define _ge_f2 __gesf2
170 1.1 christos # define _lt_f2 __ltsf2
171 1.1 christos # define _le_f2 __lesf2
172 1.1 christos # define si_to_float __floatsisf
173 1.1 christos # define float_to_si __fixsfsi
174 1.1 christos # define float_to_usi __fixunssfsi
175 1.1 christos # define negate __negsf2
176 1.1 christos # define sf_to_df __extendsfdf2
177 1.1 christos #else
178 1.1 christos # define add __adddf3
179 1.1 christos # define sub __subdf3
180 1.1 christos # define multiply __muldf3
181 1.1 christos # define divide __divdf3
182 1.1 christos # define compare __cmpdf2
183 1.1 christos # define _eq_f2 __eqdf2
184 1.1 christos # define _ne_f2 __nedf2
185 1.1 christos # define _gt_f2 __gtdf2
186 1.1 christos # define _ge_f2 __gedf2
187 1.1 christos # define _lt_f2 __ltdf2
188 1.1 christos # define _le_f2 __ledf2
189 1.1 christos # define si_to_float __floatsidf
190 1.1 christos # define float_to_si __fixdfsi
191 1.1 christos # define float_to_usi __fixunsdfsi
192 1.1 christos # define negate __negdf2
193 1.1 christos # define df_to_sf __truncdfsf2
194 1.1 christos # endif
195 1.1 christos #endif
196 1.1 christos
197 1.1 christos
198 1.1 christos #ifndef INLINE
199 1.1 christos #define INLINE __inline__
200 1.1 christos #endif
201 1.1 christos
202 1.1 christos /* Preserve the sticky-bit when shifting fractions to the right. */
203 1.1 christos #define LSHIFT(a) { a = (a & 1) | (a >> 1); }
204 1.1 christos
205 1.1 christos /* numeric parameters */
206 1.1 christos /* F_D_BITOFF is the number of bits offset between the MSB of the mantissa
207 1.1 christos of a float and of a double. Assumes there are only two float types.
208 1.1 christos (double::FRAC_BITS+double::NGARGS-(float::FRAC_BITS-float::NGARDS))
209 1.1 christos */
210 1.1 christos #define F_D_BITOFF (52+8-(23+7))
211 1.1 christos
212 1.1 christos
213 1.1 christos #define NORMAL_EXPMIN (-(EXPBIAS)+1)
214 1.1 christos #define IMPLICIT_1 (1LL<<(FRACBITS+NGARDS))
215 1.1 christos #define IMPLICIT_2 (1LL<<(FRACBITS+1+NGARDS))
216 1.1 christos
217 1.1 christos /* common types */
218 1.1 christos
219 1.1 christos typedef enum
220 1.1 christos {
221 1.1 christos CLASS_SNAN,
222 1.1 christos CLASS_QNAN,
223 1.1 christos CLASS_ZERO,
224 1.1 christos CLASS_NUMBER,
225 1.1 christos CLASS_INFINITY
226 1.1 christos } fp_class_type;
227 1.1 christos
228 1.1 christos typedef struct
229 1.1 christos {
230 1.1 christos #ifdef SMALL_MACHINE
231 1.1 christos char class;
232 1.1 christos unsigned char sign;
233 1.1 christos short normal_exp;
234 1.1 christos #else
235 1.1 christos fp_class_type class;
236 1.1 christos unsigned int sign;
237 1.1 christos int normal_exp;
238 1.1 christos #endif
239 1.1 christos
240 1.1 christos union
241 1.1 christos {
242 1.1 christos fractype ll;
243 1.1 christos halffractype l[2];
244 1.1 christos } fraction;
245 1.1 christos } fp_number_type;
246 1.1 christos
247 1.1 christos typedef union
248 1.1 christos {
249 1.1 christos FLO_type value;
250 1.1 christos #ifdef _DEBUG_BITFLOAT
251 1.1 christos int l[2];
252 1.1 christos #endif
253 1.1 christos struct
254 1.1 christos {
255 1.1 christos #ifndef FLOAT_BIT_ORDER_MISMATCH
256 1.10 christos unsigned int sign:1 ATTRIBUTE_PACKED;
257 1.10 christos unsigned int exp:EXPBITS ATTRIBUTE_PACKED;
258 1.10 christos fractype fraction:FRACBITS ATTRIBUTE_PACKED;
259 1.1 christos #else
260 1.10 christos fractype fraction:FRACBITS ATTRIBUTE_PACKED;
261 1.10 christos unsigned int exp:EXPBITS ATTRIBUTE_PACKED;
262 1.10 christos unsigned int sign:1 ATTRIBUTE_PACKED;
263 1.1 christos #endif
264 1.1 christos }
265 1.1 christos bits;
266 1.1 christos }
267 1.1 christos FLO_union_type;
268 1.1 christos
269 1.1 christos
270 1.1 christos /* end of header */
271 1.1 christos
272 1.1 christos /* IEEE "special" number predicates */
273 1.1 christos
274 1.1 christos #ifdef NO_NANS
275 1.1 christos
276 1.1 christos #define nan() 0
277 1.1 christos #define isnan(x) 0
278 1.1 christos #define isinf(x) 0
279 1.1 christos #else
280 1.1 christos
281 1.1 christos INLINE
282 1.1 christos static fp_number_type *
283 1.1 christos nan ()
284 1.1 christos {
285 1.1 christos static fp_number_type thenan;
286 1.1 christos
287 1.1 christos return &thenan;
288 1.1 christos }
289 1.1 christos
290 1.1 christos INLINE
291 1.1 christos static int
292 1.1 christos isnan ( fp_number_type * x)
293 1.1 christos {
294 1.1 christos return x->class == CLASS_SNAN || x->class == CLASS_QNAN;
295 1.1 christos }
296 1.1 christos
297 1.1 christos INLINE
298 1.1 christos static int
299 1.1 christos isinf ( fp_number_type * x)
300 1.1 christos {
301 1.1 christos return x->class == CLASS_INFINITY;
302 1.1 christos }
303 1.1 christos
304 1.1 christos #endif
305 1.1 christos
306 1.1 christos INLINE
307 1.1 christos static int
308 1.1 christos iszero ( fp_number_type * x)
309 1.1 christos {
310 1.1 christos return x->class == CLASS_ZERO;
311 1.1 christos }
312 1.1 christos
313 1.1 christos INLINE
314 1.1 christos static void
315 1.1 christos flip_sign ( fp_number_type * x)
316 1.1 christos {
317 1.1 christos x->sign = !x->sign;
318 1.1 christos }
319 1.1 christos
320 1.1 christos static FLO_type
321 1.1 christos pack_d ( fp_number_type * src)
322 1.1 christos {
323 1.1 christos FLO_union_type dst;
324 1.1 christos fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
325 1.1 christos
326 1.1 christos dst.bits.sign = src->sign;
327 1.1 christos
328 1.1 christos if (isnan (src))
329 1.1 christos {
330 1.1 christos dst.bits.exp = EXPMAX;
331 1.1 christos dst.bits.fraction = src->fraction.ll;
332 1.1 christos if (src->class == CLASS_QNAN || 1)
333 1.1 christos {
334 1.1 christos dst.bits.fraction |= QUIET_NAN;
335 1.1 christos }
336 1.1 christos }
337 1.1 christos else if (isinf (src))
338 1.1 christos {
339 1.1 christos dst.bits.exp = EXPMAX;
340 1.1 christos dst.bits.fraction = 0;
341 1.1 christos }
342 1.1 christos else if (iszero (src))
343 1.1 christos {
344 1.1 christos dst.bits.exp = 0;
345 1.1 christos dst.bits.fraction = 0;
346 1.1 christos }
347 1.1 christos else if (fraction == 0)
348 1.1 christos {
349 1.1 christos dst.value = 0;
350 1.1 christos }
351 1.1 christos else
352 1.1 christos {
353 1.1 christos if (src->normal_exp < NORMAL_EXPMIN)
354 1.1 christos {
355 1.1 christos /* This number's exponent is too low to fit into the bits
356 1.1 christos available in the number, so we'll store 0 in the exponent and
357 1.1 christos shift the fraction to the right to make up for it. */
358 1.1 christos
359 1.1 christos int shift = NORMAL_EXPMIN - src->normal_exp;
360 1.1 christos
361 1.1 christos dst.bits.exp = 0;
362 1.1 christos
363 1.1 christos if (shift > FRAC_NBITS - NGARDS)
364 1.1 christos {
365 1.1 christos /* No point shifting, since it's more that 64 out. */
366 1.1 christos fraction = 0;
367 1.1 christos }
368 1.1 christos else
369 1.1 christos {
370 1.1 christos /* Shift by the value */
371 1.1 christos fraction >>= shift;
372 1.1 christos }
373 1.1 christos fraction >>= NGARDS;
374 1.1 christos dst.bits.fraction = fraction;
375 1.1 christos }
376 1.1 christos else if (src->normal_exp > EXPBIAS)
377 1.1 christos {
378 1.1 christos dst.bits.exp = EXPMAX;
379 1.1 christos dst.bits.fraction = 0;
380 1.1 christos }
381 1.1 christos else
382 1.1 christos {
383 1.1 christos dst.bits.exp = src->normal_exp + EXPBIAS;
384 1.1 christos /* IF the gard bits are the all zero, but the first, then we're
385 1.1 christos half way between two numbers, choose the one which makes the
386 1.1 christos lsb of the answer 0. */
387 1.1 christos if ((fraction & GARDMASK) == GARDMSB)
388 1.1 christos {
389 1.1 christos if (fraction & (1 << NGARDS))
390 1.1 christos fraction += GARDROUND + 1;
391 1.1 christos }
392 1.1 christos else
393 1.1 christos {
394 1.1 christos /* Add a one to the guards to round up */
395 1.1 christos fraction += GARDROUND;
396 1.1 christos }
397 1.1 christos if (fraction >= IMPLICIT_2)
398 1.1 christos {
399 1.1 christos fraction >>= 1;
400 1.1 christos dst.bits.exp += 1;
401 1.1 christos }
402 1.1 christos fraction >>= NGARDS;
403 1.1 christos dst.bits.fraction = fraction;
404 1.1 christos }
405 1.1 christos }
406 1.1 christos return dst.value;
407 1.1 christos }
408 1.1 christos
409 1.1 christos static void
410 1.1 christos unpack_d (FLO_union_type * src, fp_number_type * dst)
411 1.1 christos {
412 1.1 christos fractype fraction = src->bits.fraction;
413 1.1 christos
414 1.1 christos dst->sign = src->bits.sign;
415 1.1 christos if (src->bits.exp == 0)
416 1.1 christos {
417 1.1 christos /* Hmm. Looks like 0 */
418 1.1 christos if (fraction == 0)
419 1.1 christos {
420 1.1 christos /* tastes like zero */
421 1.1 christos dst->class = CLASS_ZERO;
422 1.1 christos }
423 1.1 christos else
424 1.1 christos {
425 1.1 christos /* Zero exponent with non zero fraction - it's denormalized,
426 1.1 christos so there isn't a leading implicit one - we'll shift it so
427 1.1 christos it gets one. */
428 1.1 christos dst->normal_exp = src->bits.exp - EXPBIAS + 1;
429 1.1 christos fraction <<= NGARDS;
430 1.1 christos
431 1.1 christos dst->class = CLASS_NUMBER;
432 1.1 christos #if 1
433 1.1 christos while (fraction < IMPLICIT_1)
434 1.1 christos {
435 1.1 christos fraction <<= 1;
436 1.1 christos dst->normal_exp--;
437 1.1 christos }
438 1.1 christos #endif
439 1.1 christos dst->fraction.ll = fraction;
440 1.1 christos }
441 1.1 christos }
442 1.1 christos else if (src->bits.exp == EXPMAX)
443 1.1 christos {
444 1.1 christos /* Huge exponent*/
445 1.1 christos if (fraction == 0)
446 1.1 christos {
447 1.1 christos /* Attached to a zero fraction - means infinity */
448 1.1 christos dst->class = CLASS_INFINITY;
449 1.1 christos }
450 1.1 christos else
451 1.1 christos {
452 1.1 christos /* Non zero fraction, means nan */
453 1.1 christos if (dst->sign)
454 1.1 christos {
455 1.1 christos dst->class = CLASS_SNAN;
456 1.1 christos }
457 1.1 christos else
458 1.1 christos {
459 1.1 christos dst->class = CLASS_QNAN;
460 1.1 christos }
461 1.1 christos /* Keep the fraction part as the nan number */
462 1.1 christos dst->fraction.ll = fraction;
463 1.1 christos }
464 1.1 christos }
465 1.1 christos else
466 1.1 christos {
467 1.1 christos /* Nothing strange about this number */
468 1.1 christos dst->normal_exp = src->bits.exp - EXPBIAS;
469 1.1 christos dst->class = CLASS_NUMBER;
470 1.1 christos dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
471 1.1 christos }
472 1.1 christos }
473 1.1 christos
474 1.1 christos static fp_number_type *
475 1.1 christos _fpadd_parts (fp_number_type * a,
476 1.1 christos fp_number_type * b,
477 1.1 christos fp_number_type * tmp)
478 1.1 christos {
479 1.1 christos intfrac tfraction;
480 1.1 christos
481 1.1 christos /* Put commonly used fields in local variables. */
482 1.1 christos int a_normal_exp;
483 1.1 christos int b_normal_exp;
484 1.1 christos fractype a_fraction;
485 1.1 christos fractype b_fraction;
486 1.1 christos
487 1.1 christos if (isnan (a))
488 1.1 christos {
489 1.1 christos return a;
490 1.1 christos }
491 1.1 christos if (isnan (b))
492 1.1 christos {
493 1.1 christos return b;
494 1.1 christos }
495 1.1 christos if (isinf (a))
496 1.1 christos {
497 1.1 christos /* Adding infinities with opposite signs yields a NaN. */
498 1.1 christos if (isinf (b) && a->sign != b->sign)
499 1.1 christos return nan ();
500 1.1 christos return a;
501 1.1 christos }
502 1.1 christos if (isinf (b))
503 1.1 christos {
504 1.1 christos return b;
505 1.1 christos }
506 1.1 christos if (iszero (b))
507 1.1 christos {
508 1.1 christos return a;
509 1.1 christos }
510 1.1 christos if (iszero (a))
511 1.1 christos {
512 1.1 christos return b;
513 1.1 christos }
514 1.1 christos
515 1.1 christos /* Got two numbers. shift the smaller and increment the exponent till
516 1.1 christos they're the same */
517 1.1 christos {
518 1.1 christos int diff;
519 1.1 christos
520 1.1 christos a_normal_exp = a->normal_exp;
521 1.1 christos b_normal_exp = b->normal_exp;
522 1.1 christos a_fraction = a->fraction.ll;
523 1.1 christos b_fraction = b->fraction.ll;
524 1.1 christos
525 1.1 christos diff = a_normal_exp - b_normal_exp;
526 1.1 christos
527 1.1 christos if (diff < 0)
528 1.1 christos diff = -diff;
529 1.1 christos if (diff < FRAC_NBITS)
530 1.1 christos {
531 1.1 christos /* ??? This does shifts one bit at a time. Optimize. */
532 1.1 christos while (a_normal_exp > b_normal_exp)
533 1.1 christos {
534 1.1 christos b_normal_exp++;
535 1.1 christos LSHIFT (b_fraction);
536 1.1 christos }
537 1.1 christos while (b_normal_exp > a_normal_exp)
538 1.1 christos {
539 1.1 christos a_normal_exp++;
540 1.1 christos LSHIFT (a_fraction);
541 1.1 christos }
542 1.1 christos }
543 1.1 christos else
544 1.1 christos {
545 1.1 christos /* Somethings's up.. choose the biggest */
546 1.1 christos if (a_normal_exp > b_normal_exp)
547 1.1 christos {
548 1.1 christos b_normal_exp = a_normal_exp;
549 1.1 christos b_fraction = 0;
550 1.1 christos }
551 1.1 christos else
552 1.1 christos {
553 1.1 christos a_normal_exp = b_normal_exp;
554 1.1 christos a_fraction = 0;
555 1.1 christos }
556 1.1 christos }
557 1.1 christos }
558 1.1 christos
559 1.1 christos if (a->sign != b->sign)
560 1.1 christos {
561 1.1 christos if (a->sign)
562 1.1 christos {
563 1.1 christos tfraction = -a_fraction + b_fraction;
564 1.1 christos }
565 1.1 christos else
566 1.1 christos {
567 1.1 christos tfraction = a_fraction - b_fraction;
568 1.1 christos }
569 1.1 christos if (tfraction > 0)
570 1.1 christos {
571 1.1 christos tmp->sign = 0;
572 1.1 christos tmp->normal_exp = a_normal_exp;
573 1.1 christos tmp->fraction.ll = tfraction;
574 1.1 christos }
575 1.1 christos else
576 1.1 christos {
577 1.1 christos tmp->sign = 1;
578 1.1 christos tmp->normal_exp = a_normal_exp;
579 1.1 christos tmp->fraction.ll = -tfraction;
580 1.1 christos }
581 1.1 christos /* and renormalize it */
582 1.1 christos
583 1.1 christos while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
584 1.1 christos {
585 1.1 christos tmp->fraction.ll <<= 1;
586 1.1 christos tmp->normal_exp--;
587 1.1 christos }
588 1.1 christos }
589 1.1 christos else
590 1.1 christos {
591 1.1 christos tmp->sign = a->sign;
592 1.1 christos tmp->normal_exp = a_normal_exp;
593 1.1 christos tmp->fraction.ll = a_fraction + b_fraction;
594 1.1 christos }
595 1.1 christos tmp->class = CLASS_NUMBER;
596 1.1 christos /* Now the fraction is added, we have to shift down to renormalize the
597 1.1 christos number */
598 1.1 christos
599 1.1 christos if (tmp->fraction.ll >= IMPLICIT_2)
600 1.1 christos {
601 1.1 christos LSHIFT (tmp->fraction.ll);
602 1.1 christos tmp->normal_exp++;
603 1.1 christos }
604 1.1 christos return tmp;
605 1.1 christos
606 1.1 christos }
607 1.1 christos
608 1.1 christos FLO_type
609 1.1 christos add (FLO_type arg_a, FLO_type arg_b)
610 1.1 christos {
611 1.1 christos fp_number_type a;
612 1.1 christos fp_number_type b;
613 1.1 christos fp_number_type tmp;
614 1.1 christos fp_number_type *res;
615 1.1 christos
616 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
617 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
618 1.1 christos
619 1.1 christos res = _fpadd_parts (&a, &b, &tmp);
620 1.1 christos
621 1.1 christos return pack_d (res);
622 1.1 christos }
623 1.1 christos
624 1.1 christos FLO_type
625 1.1 christos sub (FLO_type arg_a, FLO_type arg_b)
626 1.1 christos {
627 1.1 christos fp_number_type a;
628 1.1 christos fp_number_type b;
629 1.1 christos fp_number_type tmp;
630 1.1 christos fp_number_type *res;
631 1.1 christos
632 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
633 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
634 1.1 christos
635 1.1 christos b.sign ^= 1;
636 1.1 christos
637 1.1 christos res = _fpadd_parts (&a, &b, &tmp);
638 1.1 christos
639 1.1 christos return pack_d (res);
640 1.1 christos }
641 1.1 christos
642 1.1 christos static fp_number_type *
643 1.1 christos _fpmul_parts ( fp_number_type * a,
644 1.1 christos fp_number_type * b,
645 1.1 christos fp_number_type * tmp)
646 1.1 christos {
647 1.1 christos fractype low = 0;
648 1.1 christos fractype high = 0;
649 1.1 christos
650 1.1 christos if (isnan (a))
651 1.1 christos {
652 1.1 christos a->sign = a->sign != b->sign;
653 1.1 christos return a;
654 1.1 christos }
655 1.1 christos if (isnan (b))
656 1.1 christos {
657 1.1 christos b->sign = a->sign != b->sign;
658 1.1 christos return b;
659 1.1 christos }
660 1.1 christos if (isinf (a))
661 1.1 christos {
662 1.1 christos if (iszero (b))
663 1.1 christos return nan ();
664 1.1 christos a->sign = a->sign != b->sign;
665 1.1 christos return a;
666 1.1 christos }
667 1.1 christos if (isinf (b))
668 1.1 christos {
669 1.1 christos if (iszero (a))
670 1.1 christos {
671 1.1 christos return nan ();
672 1.1 christos }
673 1.1 christos b->sign = a->sign != b->sign;
674 1.1 christos return b;
675 1.1 christos }
676 1.1 christos if (iszero (a))
677 1.1 christos {
678 1.1 christos a->sign = a->sign != b->sign;
679 1.1 christos return a;
680 1.1 christos }
681 1.1 christos if (iszero (b))
682 1.1 christos {
683 1.1 christos b->sign = a->sign != b->sign;
684 1.1 christos return b;
685 1.1 christos }
686 1.1 christos
687 1.1 christos /* Calculate the mantissa by multiplying both 64bit numbers to get a
688 1.1 christos 128 bit number */
689 1.1 christos {
690 1.1 christos fractype x = a->fraction.ll;
691 1.1 christos fractype ylow = b->fraction.ll;
692 1.1 christos fractype yhigh = 0;
693 1.1 christos int bit;
694 1.1 christos
695 1.1 christos #if defined(NO_DI_MODE)
696 1.1 christos {
697 1.1 christos /* ??? This does multiplies one bit at a time. Optimize. */
698 1.1 christos for (bit = 0; bit < FRAC_NBITS; bit++)
699 1.1 christos {
700 1.1 christos int carry;
701 1.1 christos
702 1.1 christos if (x & 1)
703 1.1 christos {
704 1.1 christos carry = (low += ylow) < ylow;
705 1.1 christos high += yhigh + carry;
706 1.1 christos }
707 1.1 christos yhigh <<= 1;
708 1.1 christos if (ylow & FRACHIGH)
709 1.1 christos {
710 1.1 christos yhigh |= 1;
711 1.1 christos }
712 1.1 christos ylow <<= 1;
713 1.1 christos x >>= 1;
714 1.1 christos }
715 1.1 christos }
716 1.1 christos #elif defined(FLOAT)
717 1.1 christos {
718 1.1 christos /* Multiplying two 32 bit numbers to get a 64 bit number on
719 1.1 christos a machine with DI, so we're safe */
720 1.1 christos
721 1.1 christos DItype answer = (DItype)(a->fraction.ll) * (DItype)(b->fraction.ll);
722 1.1 christos
723 1.1 christos high = answer >> 32;
724 1.1 christos low = answer;
725 1.1 christos }
726 1.1 christos #else
727 1.1 christos /* Doing a 64*64 to 128 */
728 1.1 christos {
729 1.1 christos UDItype nl = a->fraction.ll & 0xffffffff;
730 1.1 christos UDItype nh = a->fraction.ll >> 32;
731 1.1 christos UDItype ml = b->fraction.ll & 0xffffffff;
732 1.1 christos UDItype mh = b->fraction.ll >>32;
733 1.1 christos UDItype pp_ll = ml * nl;
734 1.1 christos UDItype pp_hl = mh * nl;
735 1.1 christos UDItype pp_lh = ml * nh;
736 1.1 christos UDItype pp_hh = mh * nh;
737 1.1 christos UDItype res2 = 0;
738 1.1 christos UDItype res0 = 0;
739 1.1 christos UDItype ps_hh__ = pp_hl + pp_lh;
740 1.1 christos if (ps_hh__ < pp_hl)
741 1.1 christos res2 += 0x100000000LL;
742 1.1 christos pp_hl = (ps_hh__ << 32) & 0xffffffff00000000LL;
743 1.1 christos res0 = pp_ll + pp_hl;
744 1.1 christos if (res0 < pp_ll)
745 1.1 christos res2++;
746 1.1 christos res2 += ((ps_hh__ >> 32) & 0xffffffffL) + pp_hh;
747 1.1 christos high = res2;
748 1.1 christos low = res0;
749 1.1 christos }
750 1.1 christos #endif
751 1.1 christos }
752 1.1 christos
753 1.1 christos tmp->normal_exp = a->normal_exp + b->normal_exp;
754 1.1 christos tmp->sign = a->sign != b->sign;
755 1.1 christos #ifdef FLOAT
756 1.1 christos tmp->normal_exp += 2; /* ??????????????? */
757 1.1 christos #else
758 1.1 christos tmp->normal_exp += 4; /* ??????????????? */
759 1.1 christos #endif
760 1.1 christos while (high >= IMPLICIT_2)
761 1.1 christos {
762 1.1 christos tmp->normal_exp++;
763 1.1 christos if (high & 1)
764 1.1 christos {
765 1.1 christos low >>= 1;
766 1.1 christos low |= FRACHIGH;
767 1.1 christos }
768 1.1 christos high >>= 1;
769 1.1 christos }
770 1.1 christos while (high < IMPLICIT_1)
771 1.1 christos {
772 1.1 christos tmp->normal_exp--;
773 1.1 christos
774 1.1 christos high <<= 1;
775 1.1 christos if (low & FRACHIGH)
776 1.1 christos high |= 1;
777 1.1 christos low <<= 1;
778 1.1 christos }
779 1.1 christos /* rounding is tricky. if we only round if it won't make us round later. */
780 1.1 christos #if 0
781 1.1 christos if (low & FRACHIGH2)
782 1.1 christos {
783 1.1 christos if (((high & GARDMASK) != GARDMSB)
784 1.1 christos && (((high + 1) & GARDMASK) == GARDMSB))
785 1.1 christos {
786 1.1 christos /* don't round, it gets done again later. */
787 1.1 christos }
788 1.1 christos else
789 1.1 christos {
790 1.1 christos high++;
791 1.1 christos }
792 1.1 christos }
793 1.1 christos #endif
794 1.1 christos if ((high & GARDMASK) == GARDMSB)
795 1.1 christos {
796 1.1 christos if (high & (1 << NGARDS))
797 1.1 christos {
798 1.1 christos /* half way, so round to even */
799 1.1 christos high += GARDROUND + 1;
800 1.1 christos }
801 1.1 christos else if (low)
802 1.1 christos {
803 1.1 christos /* but we really weren't half way */
804 1.1 christos high += GARDROUND + 1;
805 1.1 christos }
806 1.1 christos }
807 1.1 christos tmp->fraction.ll = high;
808 1.1 christos tmp->class = CLASS_NUMBER;
809 1.1 christos return tmp;
810 1.1 christos }
811 1.1 christos
812 1.1 christos FLO_type
813 1.1 christos multiply (FLO_type arg_a, FLO_type arg_b)
814 1.1 christos {
815 1.1 christos fp_number_type a;
816 1.1 christos fp_number_type b;
817 1.1 christos fp_number_type tmp;
818 1.1 christos fp_number_type *res;
819 1.1 christos
820 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
821 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
822 1.1 christos
823 1.1 christos res = _fpmul_parts (&a, &b, &tmp);
824 1.1 christos
825 1.1 christos return pack_d (res);
826 1.1 christos }
827 1.1 christos
828 1.1 christos static fp_number_type *
829 1.1 christos _fpdiv_parts (fp_number_type * a,
830 1.1 christos fp_number_type * b,
831 1.1 christos fp_number_type * tmp)
832 1.1 christos {
833 1.1 christos fractype low = 0;
834 1.1 christos fractype high = 0;
835 1.1 christos fractype r0, r1, y0, y1, bit;
836 1.1 christos fractype q;
837 1.1 christos fractype numerator;
838 1.1 christos fractype denominator;
839 1.1 christos fractype quotient;
840 1.1 christos fractype remainder;
841 1.1 christos
842 1.1 christos if (isnan (a))
843 1.1 christos {
844 1.1 christos return a;
845 1.1 christos }
846 1.1 christos if (isnan (b))
847 1.1 christos {
848 1.1 christos return b;
849 1.1 christos }
850 1.1 christos if (isinf (a) || iszero (a))
851 1.1 christos {
852 1.1 christos if (a->class == b->class)
853 1.1 christos return nan ();
854 1.1 christos return a;
855 1.1 christos }
856 1.1 christos a->sign = a->sign ^ b->sign;
857 1.1 christos
858 1.1 christos if (isinf (b))
859 1.1 christos {
860 1.1 christos a->fraction.ll = 0;
861 1.1 christos a->normal_exp = 0;
862 1.1 christos return a;
863 1.1 christos }
864 1.1 christos if (iszero (b))
865 1.1 christos {
866 1.1 christos a->class = CLASS_INFINITY;
867 1.1 christos return b;
868 1.1 christos }
869 1.1 christos
870 1.1 christos /* Calculate the mantissa by multiplying both 64bit numbers to get a
871 1.1 christos 128 bit number */
872 1.1 christos {
873 1.1 christos int carry;
874 1.1 christos intfrac d0, d1; /* weren't unsigned before ??? */
875 1.1 christos
876 1.1 christos /* quotient =
877 1.1 christos ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
878 1.1 christos */
879 1.1 christos
880 1.1 christos a->normal_exp = a->normal_exp - b->normal_exp;
881 1.1 christos numerator = a->fraction.ll;
882 1.1 christos denominator = b->fraction.ll;
883 1.1 christos
884 1.1 christos if (numerator < denominator)
885 1.1 christos {
886 1.1 christos /* Fraction will be less than 1.0 */
887 1.1 christos numerator *= 2;
888 1.1 christos a->normal_exp--;
889 1.1 christos }
890 1.1 christos bit = IMPLICIT_1;
891 1.1 christos quotient = 0;
892 1.1 christos /* ??? Does divide one bit at a time. Optimize. */
893 1.1 christos while (bit)
894 1.1 christos {
895 1.1 christos if (numerator >= denominator)
896 1.1 christos {
897 1.1 christos quotient |= bit;
898 1.1 christos numerator -= denominator;
899 1.1 christos }
900 1.1 christos bit >>= 1;
901 1.1 christos numerator *= 2;
902 1.1 christos }
903 1.1 christos
904 1.1 christos if ((quotient & GARDMASK) == GARDMSB)
905 1.1 christos {
906 1.1 christos if (quotient & (1 << NGARDS))
907 1.1 christos {
908 1.1 christos /* half way, so round to even */
909 1.1 christos quotient += GARDROUND + 1;
910 1.1 christos }
911 1.1 christos else if (numerator)
912 1.1 christos {
913 1.1 christos /* but we really weren't half way, more bits exist */
914 1.1 christos quotient += GARDROUND + 1;
915 1.1 christos }
916 1.1 christos }
917 1.1 christos
918 1.1 christos a->fraction.ll = quotient;
919 1.1 christos return (a);
920 1.1 christos }
921 1.1 christos }
922 1.1 christos
923 1.1 christos FLO_type
924 1.1 christos divide (FLO_type arg_a, FLO_type arg_b)
925 1.1 christos {
926 1.1 christos fp_number_type a;
927 1.1 christos fp_number_type b;
928 1.1 christos fp_number_type tmp;
929 1.1 christos fp_number_type *res;
930 1.1 christos
931 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
932 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
933 1.1 christos
934 1.1 christos res = _fpdiv_parts (&a, &b, &tmp);
935 1.1 christos
936 1.1 christos return pack_d (res);
937 1.1 christos }
938 1.1 christos
939 1.1 christos /* according to the demo, fpcmp returns a comparison with 0... thus
940 1.1 christos a<b -> -1
941 1.1 christos a==b -> 0
942 1.1 christos a>b -> +1
943 1.1 christos */
944 1.1 christos
945 1.1 christos static int
946 1.1 christos _fpcmp_parts (fp_number_type * a, fp_number_type * b)
947 1.1 christos {
948 1.1 christos #if 0
949 1.1 christos /* either nan -> unordered. Must be checked outside of this routine. */
950 1.1 christos if (isnan (a) && isnan (b))
951 1.1 christos {
952 1.1 christos return 1; /* still unordered! */
953 1.1 christos }
954 1.1 christos #endif
955 1.1 christos
956 1.1 christos if (isnan (a) || isnan (b))
957 1.1 christos {
958 1.1 christos return 1; /* how to indicate unordered compare? */
959 1.1 christos }
960 1.1 christos if (isinf (a) && isinf (b))
961 1.1 christos {
962 1.1 christos /* +inf > -inf, but +inf != +inf */
963 1.1 christos /* b \a| +inf(0)| -inf(1)
964 1.1 christos ______\+--------+--------
965 1.1 christos +inf(0)| a==b(0)| a<b(-1)
966 1.1 christos -------+--------+--------
967 1.1 christos -inf(1)| a>b(1) | a==b(0)
968 1.1 christos -------+--------+--------
969 1.1 christos So since unordered must be non zero, just line up the columns...
970 1.1 christos */
971 1.1 christos return b->sign - a->sign;
972 1.1 christos }
973 1.1 christos /* but not both... */
974 1.1 christos if (isinf (a))
975 1.1 christos {
976 1.1 christos return a->sign ? -1 : 1;
977 1.1 christos }
978 1.1 christos if (isinf (b))
979 1.1 christos {
980 1.1 christos return b->sign ? 1 : -1;
981 1.1 christos }
982 1.1 christos if (iszero (a) && iszero (b))
983 1.1 christos {
984 1.1 christos return 0;
985 1.1 christos }
986 1.1 christos if (iszero (a))
987 1.1 christos {
988 1.1 christos return b->sign ? 1 : -1;
989 1.1 christos }
990 1.1 christos if (iszero (b))
991 1.1 christos {
992 1.1 christos return a->sign ? -1 : 1;
993 1.1 christos }
994 1.1 christos /* now both are "normal". */
995 1.1 christos if (a->sign != b->sign)
996 1.1 christos {
997 1.1 christos /* opposite signs */
998 1.1 christos return a->sign ? -1 : 1;
999 1.1 christos }
1000 1.1 christos /* same sign; exponents? */
1001 1.1 christos if (a->normal_exp > b->normal_exp)
1002 1.1 christos {
1003 1.1 christos return a->sign ? -1 : 1;
1004 1.1 christos }
1005 1.1 christos if (a->normal_exp < b->normal_exp)
1006 1.1 christos {
1007 1.1 christos return a->sign ? 1 : -1;
1008 1.1 christos }
1009 1.1 christos /* same exponents; check size. */
1010 1.1 christos if (a->fraction.ll > b->fraction.ll)
1011 1.1 christos {
1012 1.1 christos return a->sign ? -1 : 1;
1013 1.1 christos }
1014 1.1 christos if (a->fraction.ll < b->fraction.ll)
1015 1.1 christos {
1016 1.1 christos return a->sign ? 1 : -1;
1017 1.1 christos }
1018 1.1 christos /* after all that, they're equal. */
1019 1.1 christos return 0;
1020 1.1 christos }
1021 1.1 christos
1022 1.1 christos CMPtype
1023 1.1 christos compare (FLO_type arg_a, FLO_type arg_b)
1024 1.1 christos {
1025 1.1 christos fp_number_type a;
1026 1.1 christos fp_number_type b;
1027 1.1 christos
1028 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
1029 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
1030 1.1 christos
1031 1.1 christos return _fpcmp_parts (&a, &b);
1032 1.1 christos }
1033 1.1 christos
1034 1.1 christos #ifndef US_SOFTWARE_GOFAST
1035 1.1 christos
1036 1.1 christos /* These should be optimized for their specific tasks someday. */
1037 1.1 christos
1038 1.1 christos CMPtype
1039 1.1 christos _eq_f2 (FLO_type arg_a, FLO_type arg_b)
1040 1.1 christos {
1041 1.1 christos fp_number_type a;
1042 1.1 christos fp_number_type b;
1043 1.1 christos
1044 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
1045 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
1046 1.1 christos
1047 1.1 christos if (isnan (&a) || isnan (&b))
1048 1.1 christos return 1; /* false, truth == 0 */
1049 1.1 christos
1050 1.1 christos return _fpcmp_parts (&a, &b) ;
1051 1.1 christos }
1052 1.1 christos
1053 1.1 christos CMPtype
1054 1.1 christos _ne_f2 (FLO_type arg_a, FLO_type arg_b)
1055 1.1 christos {
1056 1.1 christos fp_number_type a;
1057 1.1 christos fp_number_type b;
1058 1.1 christos
1059 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
1060 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
1061 1.1 christos
1062 1.1 christos if (isnan (&a) || isnan (&b))
1063 1.1 christos return 1; /* true, truth != 0 */
1064 1.1 christos
1065 1.1 christos return _fpcmp_parts (&a, &b) ;
1066 1.1 christos }
1067 1.1 christos
1068 1.1 christos CMPtype
1069 1.1 christos _gt_f2 (FLO_type arg_a, FLO_type arg_b)
1070 1.1 christos {
1071 1.1 christos fp_number_type a;
1072 1.1 christos fp_number_type b;
1073 1.1 christos
1074 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
1075 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
1076 1.1 christos
1077 1.1 christos if (isnan (&a) || isnan (&b))
1078 1.1 christos return -1; /* false, truth > 0 */
1079 1.1 christos
1080 1.1 christos return _fpcmp_parts (&a, &b);
1081 1.1 christos }
1082 1.1 christos
1083 1.1 christos CMPtype
1084 1.1 christos _ge_f2 (FLO_type arg_a, FLO_type arg_b)
1085 1.1 christos {
1086 1.1 christos fp_number_type a;
1087 1.1 christos fp_number_type b;
1088 1.1 christos
1089 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
1090 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
1091 1.1 christos
1092 1.1 christos if (isnan (&a) || isnan (&b))
1093 1.1 christos return -1; /* false, truth >= 0 */
1094 1.1 christos return _fpcmp_parts (&a, &b) ;
1095 1.1 christos }
1096 1.1 christos
1097 1.1 christos CMPtype
1098 1.1 christos _lt_f2 (FLO_type arg_a, FLO_type arg_b)
1099 1.1 christos {
1100 1.1 christos fp_number_type a;
1101 1.1 christos fp_number_type b;
1102 1.1 christos
1103 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
1104 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
1105 1.1 christos
1106 1.1 christos if (isnan (&a) || isnan (&b))
1107 1.1 christos return 1; /* false, truth < 0 */
1108 1.1 christos
1109 1.1 christos return _fpcmp_parts (&a, &b);
1110 1.1 christos }
1111 1.1 christos
1112 1.1 christos CMPtype
1113 1.1 christos _le_f2 (FLO_type arg_a, FLO_type arg_b)
1114 1.1 christos {
1115 1.1 christos fp_number_type a;
1116 1.1 christos fp_number_type b;
1117 1.1 christos
1118 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
1119 1.1 christos unpack_d ((FLO_union_type *) & arg_b, &b);
1120 1.1 christos
1121 1.1 christos if (isnan (&a) || isnan (&b))
1122 1.1 christos return 1; /* false, truth <= 0 */
1123 1.1 christos
1124 1.1 christos return _fpcmp_parts (&a, &b) ;
1125 1.1 christos }
1126 1.1 christos
1127 1.1 christos #endif /* ! US_SOFTWARE_GOFAST */
1128 1.1 christos
1129 1.1 christos FLO_type
1130 1.1 christos si_to_float (SItype arg_a)
1131 1.1 christos {
1132 1.1 christos fp_number_type in;
1133 1.1 christos
1134 1.1 christos in.class = CLASS_NUMBER;
1135 1.1 christos in.sign = arg_a < 0;
1136 1.1 christos if (!arg_a)
1137 1.1 christos {
1138 1.1 christos in.class = CLASS_ZERO;
1139 1.1 christos }
1140 1.1 christos else
1141 1.1 christos {
1142 1.1 christos in.normal_exp = FRACBITS + NGARDS;
1143 1.1 christos if (in.sign)
1144 1.1 christos {
1145 1.1 christos /* Special case for minint, since there is no +ve integer
1146 1.1 christos representation for it */
1147 1.1 christos if (arg_a == 0x80000000)
1148 1.1 christos {
1149 1.1 christos return -2147483648.0;
1150 1.1 christos }
1151 1.1 christos in.fraction.ll = (-arg_a);
1152 1.1 christos }
1153 1.1 christos else
1154 1.1 christos in.fraction.ll = arg_a;
1155 1.1 christos
1156 1.1 christos while (in.fraction.ll < (1LL << (FRACBITS + NGARDS)))
1157 1.1 christos {
1158 1.1 christos in.fraction.ll <<= 1;
1159 1.1 christos in.normal_exp -= 1;
1160 1.1 christos }
1161 1.1 christos }
1162 1.1 christos return pack_d (&in);
1163 1.1 christos }
1164 1.1 christos
1165 1.1 christos SItype
1166 1.1 christos float_to_si (FLO_type arg_a)
1167 1.1 christos {
1168 1.1 christos fp_number_type a;
1169 1.1 christos SItype tmp;
1170 1.1 christos
1171 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
1172 1.1 christos if (iszero (&a))
1173 1.1 christos return 0;
1174 1.1 christos if (isnan (&a))
1175 1.1 christos return 0;
1176 1.1 christos /* get reasonable MAX_SI_INT... */
1177 1.1 christos if (isinf (&a))
1178 1.1 christos return a.sign ? MAX_SI_INT : (-MAX_SI_INT)-1;
1179 1.1 christos /* it is a number, but a small one */
1180 1.1 christos if (a.normal_exp < 0)
1181 1.1 christos return 0;
1182 1.1 christos if (a.normal_exp > 30)
1183 1.1 christos return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
1184 1.1 christos tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
1185 1.1 christos return a.sign ? (-tmp) : (tmp);
1186 1.1 christos }
1187 1.1 christos
1188 1.1 christos #ifdef US_SOFTWARE_GOFAST
1189 1.1 christos /* While libgcc2.c defines its own __fixunssfsi and __fixunsdfsi routines,
1190 1.1 christos we also define them for GOFAST because the ones in libgcc2.c have the
1191 1.1 christos wrong names and I'd rather define these here and keep GOFAST CYG-LOC's
1192 1.1 christos out of libgcc2.c. We can't define these here if not GOFAST because then
1193 1.1 christos there'd be duplicate copies. */
1194 1.1 christos
1195 1.1 christos USItype
1196 1.1 christos float_to_usi (FLO_type arg_a)
1197 1.1 christos {
1198 1.1 christos fp_number_type a;
1199 1.1 christos
1200 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
1201 1.1 christos if (iszero (&a))
1202 1.1 christos return 0;
1203 1.1 christos if (isnan (&a))
1204 1.1 christos return 0;
1205 1.1 christos /* get reasonable MAX_USI_INT... */
1206 1.1 christos if (isinf (&a))
1207 1.1 christos return a.sign ? MAX_USI_INT : 0;
1208 1.1 christos /* it is a negative number */
1209 1.1 christos if (a.sign)
1210 1.1 christos return 0;
1211 1.1 christos /* it is a number, but a small one */
1212 1.1 christos if (a.normal_exp < 0)
1213 1.1 christos return 0;
1214 1.1 christos if (a.normal_exp > 31)
1215 1.1 christos return MAX_USI_INT;
1216 1.1 christos else if (a.normal_exp > (FRACBITS + NGARDS))
1217 1.1 christos return a.fraction.ll << ((FRACBITS + NGARDS) - a.normal_exp);
1218 1.1 christos else
1219 1.1 christos return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
1220 1.1 christos }
1221 1.1 christos #endif
1222 1.1 christos
1223 1.1 christos FLO_type
1224 1.1 christos negate (FLO_type arg_a)
1225 1.1 christos {
1226 1.1 christos fp_number_type a;
1227 1.1 christos
1228 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &a);
1229 1.1 christos flip_sign (&a);
1230 1.1 christos return pack_d (&a);
1231 1.1 christos }
1232 1.1 christos
1233 1.1 christos #ifdef FLOAT
1234 1.1 christos
1235 1.1 christos SFtype
1236 1.1 christos __make_fp(fp_class_type class,
1237 1.1 christos unsigned int sign,
1238 1.1 christos int exp,
1239 1.1 christos USItype frac)
1240 1.1 christos {
1241 1.1 christos fp_number_type in;
1242 1.1 christos
1243 1.1 christos in.class = class;
1244 1.1 christos in.sign = sign;
1245 1.1 christos in.normal_exp = exp;
1246 1.1 christos in.fraction.ll = frac;
1247 1.1 christos return pack_d (&in);
1248 1.1 christos }
1249 1.1 christos
1250 1.1 christos #ifndef FLOAT_ONLY
1251 1.1 christos
1252 1.1 christos /* This enables one to build an fp library that supports float but not double.
1253 1.1 christos Otherwise, we would get an undefined reference to __make_dp.
1254 1.1 christos This is needed for some 8-bit ports that can't handle well values that
1255 1.1 christos are 8-bytes in size, so we just don't support double for them at all. */
1256 1.1 christos
1257 1.1 christos extern DFtype __make_dp (fp_class_type, unsigned int, int, UDItype frac);
1258 1.1 christos
1259 1.1 christos DFtype
1260 1.1 christos sf_to_df (SFtype arg_a)
1261 1.1 christos {
1262 1.1 christos fp_number_type in;
1263 1.1 christos
1264 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &in);
1265 1.1 christos return __make_dp (in.class, in.sign, in.normal_exp,
1266 1.1 christos ((UDItype) in.fraction.ll) << F_D_BITOFF);
1267 1.1 christos }
1268 1.1 christos
1269 1.1 christos #endif
1270 1.1 christos #endif
1271 1.1 christos
1272 1.1 christos #ifndef FLOAT
1273 1.1 christos
1274 1.1 christos extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
1275 1.1 christos
1276 1.1 christos DFtype
1277 1.1 christos __make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
1278 1.1 christos {
1279 1.1 christos fp_number_type in;
1280 1.1 christos
1281 1.1 christos in.class = class;
1282 1.1 christos in.sign = sign;
1283 1.1 christos in.normal_exp = exp;
1284 1.1 christos in.fraction.ll = frac;
1285 1.1 christos return pack_d (&in);
1286 1.1 christos }
1287 1.1 christos
1288 1.1 christos SFtype
1289 1.1 christos df_to_sf (DFtype arg_a)
1290 1.1 christos {
1291 1.1 christos fp_number_type in;
1292 1.1 christos
1293 1.1 christos unpack_d ((FLO_union_type *) & arg_a, &in);
1294 1.1 christos return __make_fp (in.class, in.sign, in.normal_exp,
1295 1.1 christos in.fraction.ll >> F_D_BITOFF);
1296 1.1 christos }
1297 1.1 christos
1298 1.1 christos #endif
1299