1 /* $OpenBSD: softfloat-specialize.h,v 1.2 2015/09/13 14:23:43 miod Exp $ */
2 /* $NetBSD: softfloat-specialize,v 1.3 2002/05/12 13:12:45 bjh21 Exp $ */
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;
float_raise(fp_except flags)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 DEF_STRONG(float_raise);
68
69 /*
70 -------------------------------------------------------------------------------
71 Internal canonical NaN format.
72 -------------------------------------------------------------------------------
73 */
74 typedef struct {
75 flag sign;
76 bits64 high, low;
77 } commonNaNT;
78
79 /*
80 -------------------------------------------------------------------------------
81 The pattern for a default generated single-precision NaN.
82 -------------------------------------------------------------------------------
83 */
84 #define float32_default_nan 0xFFFFFFFF
85
86 /*
87 -------------------------------------------------------------------------------
88 Returns 1 if the single-precision floating-point value `a' is a NaN;
89 otherwise returns 0.
90 -------------------------------------------------------------------------------
91 */
92 #ifdef SOFTFLOAT_FOR_GCC
93 static
94 #endif
float32_is_nan(float32 a)95 flag float32_is_nan( float32 a )
96 {
97
98 return ( 0xFF000000 < (bits32) ( a<<1 ) );
99
100 }
101
102 /*
103 -------------------------------------------------------------------------------
104 Returns 1 if the single-precision floating-point value `a' is a signaling
105 NaN; otherwise returns 0.
106 -------------------------------------------------------------------------------
107 */
108 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC)
109 static
110 #endif
float32_is_signaling_nan(float32 a)111 flag float32_is_signaling_nan( float32 a )
112 {
113
114 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
115
116 }
117
118 /*
119 -------------------------------------------------------------------------------
120 Returns the result of converting the single-precision floating-point NaN
121 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
122 exception is raised.
123 -------------------------------------------------------------------------------
124 */
float32ToCommonNaN(float32 a)125 static commonNaNT float32ToCommonNaN( float32 a )
126 {
127 commonNaNT z;
128
129 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
130 z.sign = a>>31;
131 z.low = 0;
132 z.high = ( (bits64) a )<<41;
133 return z;
134
135 }
136
137 /*
138 -------------------------------------------------------------------------------
139 Returns the result of converting the canonical NaN `a' to the single-
140 precision floating-point format.
141 -------------------------------------------------------------------------------
142 */
commonNaNToFloat32(commonNaNT a)143 static float32 commonNaNToFloat32( commonNaNT a )
144 {
145
146 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
147
148 }
149
150 /*
151 -------------------------------------------------------------------------------
152 Takes two single-precision floating-point values `a' and `b', one of which
153 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
154 signaling NaN, the invalid exception is raised.
155 -------------------------------------------------------------------------------
156 */
propagateFloat32NaN(float32 a,float32 b)157 static float32 propagateFloat32NaN( float32 a, float32 b )
158 {
159 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
160
161 aIsNaN = float32_is_nan( a );
162 aIsSignalingNaN = float32_is_signaling_nan( a );
163 bIsNaN = float32_is_nan( b );
164 bIsSignalingNaN = float32_is_signaling_nan( b );
165 a |= 0x00400000;
166 b |= 0x00400000;
167 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
168 if ( aIsNaN ) {
169 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
170 }
171 else {
172 return b;
173 }
174
175 }
176
177 /*
178 -------------------------------------------------------------------------------
179 The pattern for a default generated double-precision NaN.
180 -------------------------------------------------------------------------------
181 */
182 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
183
184 /*
185 -------------------------------------------------------------------------------
186 Returns 1 if the double-precision floating-point value `a' is a NaN;
187 otherwise returns 0.
188 -------------------------------------------------------------------------------
189 */
190 #ifdef SOFTFLOAT_FOR_GCC
191 static
192 #endif
float64_is_nan(float64 a)193 flag float64_is_nan( float64 a )
194 {
195
196 return ( LIT64( 0xFFE0000000000000 ) <
197 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
198
199 }
200
201 /*
202 -------------------------------------------------------------------------------
203 Returns 1 if the double-precision floating-point value `a' is a signaling
204 NaN; otherwise returns 0.
205 -------------------------------------------------------------------------------
206 */
207 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC)
208 static
209 #endif
float64_is_signaling_nan(float64 a)210 flag float64_is_signaling_nan( float64 a )
211 {
212
213 return
214 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
215 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
216
217 }
218
219 /*
220 -------------------------------------------------------------------------------
221 Returns the result of converting the double-precision floating-point NaN
222 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
223 exception is raised.
224 -------------------------------------------------------------------------------
225 */
float64ToCommonNaN(float64 a)226 static commonNaNT float64ToCommonNaN( float64 a )
227 {
228 commonNaNT z;
229
230 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
231 z.sign = FLOAT64_DEMANGLE(a)>>63;
232 z.low = 0;
233 z.high = FLOAT64_DEMANGLE(a)<<12;
234 return z;
235
236 }
237
238 /*
239 -------------------------------------------------------------------------------
240 Returns the result of converting the canonical NaN `a' to the double-
241 precision floating-point format.
242 -------------------------------------------------------------------------------
243 */
commonNaNToFloat64(commonNaNT a)244 static float64 commonNaNToFloat64( commonNaNT a )
245 {
246
247 return FLOAT64_MANGLE(
248 ( ( (bits64) a.sign )<<63 )
249 | LIT64( 0x7FF8000000000000 )
250 | ( a.high>>12 ) );
251
252 }
253
254 /*
255 -------------------------------------------------------------------------------
256 Takes two double-precision floating-point values `a' and `b', one of which
257 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
258 signaling NaN, the invalid exception is raised.
259 -------------------------------------------------------------------------------
260 */
propagateFloat64NaN(float64 a,float64 b)261 static float64 propagateFloat64NaN( float64 a, float64 b )
262 {
263 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
264
265 aIsNaN = float64_is_nan( a );
266 aIsSignalingNaN = float64_is_signaling_nan( a );
267 bIsNaN = float64_is_nan( b );
268 bIsSignalingNaN = float64_is_signaling_nan( b );
269 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
270 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
271 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
272 if ( aIsNaN ) {
273 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
274 }
275 else {
276 return b;
277 }
278
279 }
280
281 #ifdef FLOATX80
282
283 /*
284 -------------------------------------------------------------------------------
285 The pattern for a default generated extended double-precision NaN. The
286 `high' and `low' values hold the most- and least-significant bits,
287 respectively.
288 -------------------------------------------------------------------------------
289 */
290 #define floatx80_default_nan_high 0xFFFF
291 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
292
293 /*
294 -------------------------------------------------------------------------------
295 Returns 1 if the extended double-precision floating-point value `a' is a
296 NaN; otherwise returns 0.
297 -------------------------------------------------------------------------------
298 */
floatx80_is_nan(floatx80 a)299 flag floatx80_is_nan( floatx80 a )
300 {
301
302 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
303
304 }
305
306 /*
307 -------------------------------------------------------------------------------
308 Returns 1 if the extended double-precision floating-point value `a' is a
309 signaling NaN; otherwise returns 0.
310 -------------------------------------------------------------------------------
311 */
floatx80_is_signaling_nan(floatx80 a)312 flag floatx80_is_signaling_nan( floatx80 a )
313 {
314 bits64 aLow;
315
316 aLow = a.low & ~ LIT64( 0x4000000000000000 );
317 return
318 ( ( a.high & 0x7FFF ) == 0x7FFF )
319 && (bits64) ( aLow<<1 )
320 && ( a.low == aLow );
321
322 }
323
324 /*
325 -------------------------------------------------------------------------------
326 Returns the result of converting the extended double-precision floating-
327 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
328 invalid exception is raised.
329 -------------------------------------------------------------------------------
330 */
floatx80ToCommonNaN(floatx80 a)331 static commonNaNT floatx80ToCommonNaN( floatx80 a )
332 {
333 commonNaNT z;
334
335 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
336 z.sign = a.high>>15;
337 z.low = 0;
338 z.high = a.low<<1;
339 return z;
340
341 }
342
343 /*
344 -------------------------------------------------------------------------------
345 Returns the result of converting the canonical NaN `a' to the extended
346 double-precision floating-point format.
347 -------------------------------------------------------------------------------
348 */
commonNaNToFloatx80(commonNaNT a)349 static floatx80 commonNaNToFloatx80( commonNaNT a )
350 {
351 floatx80 z;
352
353 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
354 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
355 return z;
356
357 }
358
359 /*
360 -------------------------------------------------------------------------------
361 Takes two extended double-precision floating-point values `a' and `b', one
362 of which is a NaN, and returns the appropriate NaN result. If either `a' or
363 `b' is a signaling NaN, the invalid exception is raised.
364 -------------------------------------------------------------------------------
365 */
propagateFloatx80NaN(floatx80 a,floatx80 b)366 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
367 {
368 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
369
370 aIsNaN = floatx80_is_nan( a );
371 aIsSignalingNaN = floatx80_is_signaling_nan( a );
372 bIsNaN = floatx80_is_nan( b );
373 bIsSignalingNaN = floatx80_is_signaling_nan( b );
374 a.low |= LIT64( 0xC000000000000000 );
375 b.low |= LIT64( 0xC000000000000000 );
376 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
377 if ( aIsNaN ) {
378 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
379 }
380 else {
381 return b;
382 }
383
384 }
385
386 #endif
387
388 #ifdef FLOAT128
389
390 /*
391 -------------------------------------------------------------------------------
392 The pattern for a default generated quadruple-precision NaN. The `high' and
393 `low' values hold the most- and least-significant bits, respectively.
394 -------------------------------------------------------------------------------
395 */
396 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
397 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
398
399 /*
400 -------------------------------------------------------------------------------
401 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
402 otherwise returns 0.
403 -------------------------------------------------------------------------------
404 */
float128_is_nan(float128 a)405 flag float128_is_nan( float128 a )
406 {
407
408 return
409 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
410 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
411
412 }
413
414 /*
415 -------------------------------------------------------------------------------
416 Returns 1 if the quadruple-precision floating-point value `a' is a
417 signaling NaN; otherwise returns 0.
418 -------------------------------------------------------------------------------
419 */
float128_is_signaling_nan(float128 a)420 flag float128_is_signaling_nan( float128 a )
421 {
422
423 return
424 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
425 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
426
427 }
428
429 /*
430 -------------------------------------------------------------------------------
431 Returns the result of converting the quadruple-precision floating-point NaN
432 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
433 exception is raised.
434 -------------------------------------------------------------------------------
435 */
float128ToCommonNaN(float128 a)436 static commonNaNT float128ToCommonNaN( float128 a )
437 {
438 commonNaNT z;
439
440 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
441 z.sign = a.high>>63;
442 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
443 return z;
444
445 }
446
447 /*
448 -------------------------------------------------------------------------------
449 Returns the result of converting the canonical NaN `a' to the quadruple-
450 precision floating-point format.
451 -------------------------------------------------------------------------------
452 */
commonNaNToFloat128(commonNaNT a)453 static float128 commonNaNToFloat128( commonNaNT a )
454 {
455 float128 z;
456
457 shift128Right( a.high, a.low, 16, &z.high, &z.low );
458 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
459 return z;
460
461 }
462
463 /*
464 -------------------------------------------------------------------------------
465 Takes two quadruple-precision floating-point values `a' and `b', one of
466 which is a NaN, and returns the appropriate NaN result. If either `a' or
467 `b' is a signaling NaN, the invalid exception is raised.
468 -------------------------------------------------------------------------------
469 */
propagateFloat128NaN(float128 a,float128 b)470 static float128 propagateFloat128NaN( float128 a, float128 b )
471 {
472 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
473
474 aIsNaN = float128_is_nan( a );
475 aIsSignalingNaN = float128_is_signaling_nan( a );
476 bIsNaN = float128_is_nan( b );
477 bIsSignalingNaN = float128_is_signaling_nan( b );
478 a.high |= LIT64( 0x0000800000000000 );
479 b.high |= LIT64( 0x0000800000000000 );
480 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
481 if ( aIsNaN ) {
482 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
483 }
484 else {
485 return b;
486 }
487
488 }
489
490 #endif
491
492