]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - lib/libc/softfloat/softfloat-specialize
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / lib / libc / softfloat / softfloat-specialize
1 /*      $NetBSD: softfloat-specialize,v 1.3 2002/05/12 13:12:45 bjh21 Exp $     */
2 /* $FreeBSD$ */
3
4 /* This is a derivative work. */
5
6 /*
7 ===============================================================================
8
9 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
10 Arithmetic Package, Release 2a.
11
12 Written by John R. Hauser.  This work was made possible in part by the
13 International Computer Science Institute, located at Suite 600, 1947 Center
14 Street, Berkeley, California 94704.  Funding was partially provided by the
15 National Science Foundation under grant MIP-9311980.  The original version
16 of this code was written as part of a project to build a fixed-point vector
17 processor in collaboration with the University of California at Berkeley,
18 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
19 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
20 arithmetic/SoftFloat.html'.
21
22 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
23 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
24 TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
25 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
26 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
27
28 Derivative works are acceptable, even for commercial purposes, so long as
29 (1) they include prominent notice that the work is derivative, and (2) they
30 include prominent notice akin to these four paragraphs for those parts of
31 this code that are retained.
32
33 ===============================================================================
34 */
35
36 #include <signal.h>
37
38 /*
39 -------------------------------------------------------------------------------
40 Underflow tininess-detection mode, statically initialized to default value.
41 (The declaration in `softfloat.h' must match the `int8' type here.)
42 -------------------------------------------------------------------------------
43 */
44 #ifdef SOFTFLOAT_FOR_GCC
45 static
46 #endif
47 int8 float_detect_tininess = float_tininess_after_rounding;
48
49 /*
50 -------------------------------------------------------------------------------
51 Raises the exceptions specified by `flags'.  Floating-point traps can be
52 defined here if desired.  It is currently not possible for such a trap to
53 substitute a result value.  If traps are not implemented, this routine
54 should be simply `float_exception_flags |= flags;'.
55 -------------------------------------------------------------------------------
56 */
57 fp_except float_exception_mask = 0;
58 void float_raise( fp_except flags )
59 {
60
61     float_exception_flags |= flags;
62
63     if ( flags & float_exception_mask ) {
64         raise( SIGFPE );
65     }
66 }
67
68 /*
69 -------------------------------------------------------------------------------
70 Internal canonical NaN format.
71 -------------------------------------------------------------------------------
72 */
73 typedef struct {
74     flag sign;
75     bits64 high, low;
76 } commonNaNT;
77
78 /*
79 -------------------------------------------------------------------------------
80 The pattern for a default generated single-precision NaN.
81 -------------------------------------------------------------------------------
82 */
83 #define float32_default_nan 0xFFFFFFFF
84
85 /*
86 -------------------------------------------------------------------------------
87 Returns 1 if the single-precision floating-point value `a' is a NaN;
88 otherwise returns 0.
89 -------------------------------------------------------------------------------
90 */
91 #ifdef SOFTFLOAT_FOR_GCC
92 static
93 #endif
94 flag float32_is_nan( float32 a )
95 {
96
97     return ( 0xFF000000 < (bits32) ( a<<1 ) );
98
99 }
100
101 /*
102 -------------------------------------------------------------------------------
103 Returns 1 if the single-precision floating-point value `a' is a signaling
104 NaN; otherwise returns 0.
105 -------------------------------------------------------------------------------
106 */
107 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC)
108 static
109 #endif
110 flag float32_is_signaling_nan( float32 a )
111 {
112
113     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
114
115 }
116
117 /*
118 -------------------------------------------------------------------------------
119 Returns the result of converting the single-precision floating-point NaN
120 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
121 exception is raised.
122 -------------------------------------------------------------------------------
123 */
124 static commonNaNT float32ToCommonNaN( float32 a )
125 {
126     commonNaNT z;
127
128     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
129     z.sign = a>>31;
130     z.low = 0;
131     z.high = ( (bits64) a )<<41;
132     return z;
133
134 }
135
136 /*
137 -------------------------------------------------------------------------------
138 Returns the result of converting the canonical NaN `a' to the single-
139 precision floating-point format.
140 -------------------------------------------------------------------------------
141 */
142 static float32 commonNaNToFloat32( commonNaNT a )
143 {
144
145     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
146
147 }
148
149 /*
150 -------------------------------------------------------------------------------
151 Takes two single-precision floating-point values `a' and `b', one of which
152 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
153 signaling NaN, the invalid exception is raised.
154 -------------------------------------------------------------------------------
155 */
156 static float32 propagateFloat32NaN( float32 a, float32 b )
157 {
158     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
159
160     aIsNaN = float32_is_nan( a );
161     aIsSignalingNaN = float32_is_signaling_nan( a );
162     bIsNaN = float32_is_nan( b );
163     bIsSignalingNaN = float32_is_signaling_nan( b );
164     a |= 0x00400000;
165     b |= 0x00400000;
166     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
167     if ( aIsNaN ) {
168         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
169     }
170     else {
171         return b;
172     }
173
174 }
175
176 /*
177 -------------------------------------------------------------------------------
178 The pattern for a default generated double-precision NaN.
179 -------------------------------------------------------------------------------
180 */
181 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
182
183 /*
184 -------------------------------------------------------------------------------
185 Returns 1 if the double-precision floating-point value `a' is a NaN;
186 otherwise returns 0.
187 -------------------------------------------------------------------------------
188 */
189 #ifdef SOFTFLOAT_FOR_GCC
190 static
191 #endif
192 flag float64_is_nan( float64 a )
193 {
194
195     return ( LIT64( 0xFFE0000000000000 ) <
196              (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
197
198 }
199
200 /*
201 -------------------------------------------------------------------------------
202 Returns 1 if the double-precision floating-point value `a' is a signaling
203 NaN; otherwise returns 0.
204 -------------------------------------------------------------------------------
205 */
206 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC)
207 static
208 #endif
209 flag float64_is_signaling_nan( float64 a )
210 {
211
212     return
213            ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
214         && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
215
216 }
217
218 /*
219 -------------------------------------------------------------------------------
220 Returns the result of converting the double-precision floating-point NaN
221 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
222 exception is raised.
223 -------------------------------------------------------------------------------
224 */
225 static commonNaNT float64ToCommonNaN( float64 a )
226 {
227     commonNaNT z;
228
229     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
230     z.sign = FLOAT64_DEMANGLE(a)>>63;
231     z.low = 0;
232     z.high = FLOAT64_DEMANGLE(a)<<12;
233     return z;
234
235 }
236
237 /*
238 -------------------------------------------------------------------------------
239 Returns the result of converting the canonical NaN `a' to the double-
240 precision floating-point format.
241 -------------------------------------------------------------------------------
242 */
243 static float64 commonNaNToFloat64( commonNaNT a )
244 {
245
246     return FLOAT64_MANGLE(
247         ( ( (bits64) a.sign )<<63 )
248         | LIT64( 0x7FF8000000000000 )
249         | ( a.high>>12 ) );
250
251 }
252
253 /*
254 -------------------------------------------------------------------------------
255 Takes two double-precision floating-point values `a' and `b', one of which
256 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
257 signaling NaN, the invalid exception is raised.
258 -------------------------------------------------------------------------------
259 */
260 static float64 propagateFloat64NaN( float64 a, float64 b )
261 {
262     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
263
264     aIsNaN = float64_is_nan( a );
265     aIsSignalingNaN = float64_is_signaling_nan( a );
266     bIsNaN = float64_is_nan( b );
267     bIsSignalingNaN = float64_is_signaling_nan( b );
268     a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
269     b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
270     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
271     if ( aIsNaN ) {
272         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
273     }
274     else {
275         return b;
276     }
277
278 }
279
280 #ifdef FLOATX80
281
282 /*
283 -------------------------------------------------------------------------------
284 The pattern for a default generated extended double-precision NaN.  The
285 `high' and `low' values hold the most- and least-significant bits,
286 respectively.
287 -------------------------------------------------------------------------------
288 */
289 #define floatx80_default_nan_high 0xFFFF
290 #define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
291
292 /*
293 -------------------------------------------------------------------------------
294 Returns 1 if the extended double-precision floating-point value `a' is a
295 NaN; otherwise returns 0.
296 -------------------------------------------------------------------------------
297 */
298 flag floatx80_is_nan( floatx80 a )
299 {
300
301     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
302
303 }
304
305 /*
306 -------------------------------------------------------------------------------
307 Returns 1 if the extended double-precision floating-point value `a' is a
308 signaling NaN; otherwise returns 0.
309 -------------------------------------------------------------------------------
310 */
311 flag floatx80_is_signaling_nan( floatx80 a )
312 {
313     bits64 aLow;
314
315     aLow = a.low & ~ LIT64( 0x4000000000000000 );
316     return
317            ( ( a.high & 0x7FFF ) == 0x7FFF )
318         && (bits64) ( aLow<<1 )
319         && ( a.low == aLow );
320
321 }
322
323 /*
324 -------------------------------------------------------------------------------
325 Returns the result of converting the extended double-precision floating-
326 point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
327 invalid exception is raised.
328 -------------------------------------------------------------------------------
329 */
330 static commonNaNT floatx80ToCommonNaN( floatx80 a )
331 {
332     commonNaNT z;
333
334     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
335     z.sign = a.high>>15;
336     z.low = 0;
337     z.high = a.low<<1;
338     return z;
339
340 }
341
342 /*
343 -------------------------------------------------------------------------------
344 Returns the result of converting the canonical NaN `a' to the extended
345 double-precision floating-point format.
346 -------------------------------------------------------------------------------
347 */
348 static floatx80 commonNaNToFloatx80( commonNaNT a )
349 {
350     floatx80 z;
351
352     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
353     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
354     return z;
355
356 }
357
358 /*
359 -------------------------------------------------------------------------------
360 Takes two extended double-precision floating-point values `a' and `b', one
361 of which is a NaN, and returns the appropriate NaN result.  If either `a' or
362 `b' is a signaling NaN, the invalid exception is raised.
363 -------------------------------------------------------------------------------
364 */
365 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
366 {
367     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
368
369     aIsNaN = floatx80_is_nan( a );
370     aIsSignalingNaN = floatx80_is_signaling_nan( a );
371     bIsNaN = floatx80_is_nan( b );
372     bIsSignalingNaN = floatx80_is_signaling_nan( b );
373     a.low |= LIT64( 0xC000000000000000 );
374     b.low |= LIT64( 0xC000000000000000 );
375     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
376     if ( aIsNaN ) {
377         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
378     }
379     else {
380         return b;
381     }
382
383 }
384
385 #endif
386
387 #ifdef FLOAT128
388
389 /*
390 -------------------------------------------------------------------------------
391 The pattern for a default generated quadruple-precision NaN.  The `high' and
392 `low' values hold the most- and least-significant bits, respectively.
393 -------------------------------------------------------------------------------
394 */
395 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
396 #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
397
398 /*
399 -------------------------------------------------------------------------------
400 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
401 otherwise returns 0.
402 -------------------------------------------------------------------------------
403 */
404 flag float128_is_nan( float128 a )
405 {
406
407     return
408            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
409         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
410
411 }
412
413 /*
414 -------------------------------------------------------------------------------
415 Returns 1 if the quadruple-precision floating-point value `a' is a
416 signaling NaN; otherwise returns 0.
417 -------------------------------------------------------------------------------
418 */
419 flag float128_is_signaling_nan( float128 a )
420 {
421
422     return
423            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
424         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
425
426 }
427
428 /*
429 -------------------------------------------------------------------------------
430 Returns the result of converting the quadruple-precision floating-point NaN
431 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
432 exception is raised.
433 -------------------------------------------------------------------------------
434 */
435 static commonNaNT float128ToCommonNaN( float128 a )
436 {
437     commonNaNT z;
438
439     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
440     z.sign = a.high>>63;
441     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
442     return z;
443
444 }
445
446 /*
447 -------------------------------------------------------------------------------
448 Returns the result of converting the canonical NaN `a' to the quadruple-
449 precision floating-point format.
450 -------------------------------------------------------------------------------
451 */
452 static float128 commonNaNToFloat128( commonNaNT a )
453 {
454     float128 z;
455
456     shift128Right( a.high, a.low, 16, &z.high, &z.low );
457     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
458     return z;
459
460 }
461
462 /*
463 -------------------------------------------------------------------------------
464 Takes two quadruple-precision floating-point values `a' and `b', one of
465 which is a NaN, and returns the appropriate NaN result.  If either `a' or
466 `b' is a signaling NaN, the invalid exception is raised.
467 -------------------------------------------------------------------------------
468 */
469 static float128 propagateFloat128NaN( float128 a, float128 b )
470 {
471     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
472
473     aIsNaN = float128_is_nan( a );
474     aIsSignalingNaN = float128_is_signaling_nan( a );
475     bIsNaN = float128_is_nan( b );
476     bIsSignalingNaN = float128_is_signaling_nan( b );
477     a.high |= LIT64( 0x0000800000000000 );
478     b.high |= LIT64( 0x0000800000000000 );
479     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
480     if ( aIsNaN ) {
481         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
482     }
483     else {
484         return b;
485     }
486
487 }
488
489 #endif
490