2 /*============================================================================
6 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
7 Arithmetic Package, Release 2b.
9 Written by John R. Hauser. This work was made possible in part by the
10 International Computer Science Institute, located at Suite 600, 1947 Center
11 Street, Berkeley, California 94704. Funding was partially provided by the
12 National Science Foundation under grant MIP-9311980. The original version
13 of this code was written as part of a project to build a fixed-point vector
14 processor in collaboration with the University of California at Berkeley,
15 overseen by Profs. Nelson Morgan and John Wawrzynek. More information
16 is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
17 arithmetic/SoftFloat.html'.
19 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
20 been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
21 RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
22 AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
23 COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
24 EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
25 INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
26 OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
28 Derivative works are acceptable, even for commercial purposes, so long as
29 (1) the source code for the derivative work includes prominent notice that
30 the work is derivative, and (2) the source code includes prominent notice with
31 these four paragraphs for those parts of this code that are retained.
33 =============================================================================*/
35 /*----------------------------------------------------------------------------
36 | Internal canonical NaN format.
37 *----------------------------------------------------------------------------*/
44 /*----------------------------------------------------------------------------
45 | The pattern for a default generated single-precision NaN.
46 *----------------------------------------------------------------------------*/
47 #define float32Bits_defaultNaN 0xFFC00000
49 /*----------------------------------------------------------------------------
50 | Returns 1 if the single-precision floating-point value `a' is a NaN;
51 | otherwise, returns 0.
52 *----------------------------------------------------------------------------*/
54 #define softfloat_isNaNFloat32Bits( a ) ( 0xFF000000 < (uint32_t) ( a )<<1 )
56 /*----------------------------------------------------------------------------
57 | Returns 1 if the single-precision floating-point value `a' is a signaling
58 | NaN; otherwise, returns 0.
59 *----------------------------------------------------------------------------*/
60 inline bool softfloat_isSigNaNFloat32Bits( uint32_t a
)
61 { return ( ( a
>>22 & 0x1FF ) == 0x1FE ) && ( a
& 0x003FFFFF ); }
63 /*----------------------------------------------------------------------------
64 *----------------------------------------------------------------------------*/
65 commonNaNT
softfloat_NaNFromFloat32Bits( uint32_t );
66 uint32_t softfloat_float32BitsFromNaN( commonNaNT
);
67 uint32_t softfloat_propNaNFloat32Bits( uint32_t, uint32_t );
69 /*----------------------------------------------------------------------------
70 | The pattern for a default generated double-precision NaN.
71 *----------------------------------------------------------------------------*/
72 #define float64Bits_defaultNaN 0xFFF8000000000000
74 /*----------------------------------------------------------------------------
75 | Returns 1 if the double-precision floating-point value `a' is a NaN;
76 | otherwise, returns 0.
77 *----------------------------------------------------------------------------*/
79 #define softfloat_isNaNFloat64Bits( a ) ( 0xFFE0000000000000 < (uint64_t) ( a )<<1 )
86 /*----------------------------------------------------------------------------
87 | Returns 1 if the double-precision floating-point value `a' is a signaling
88 | NaN; otherwise, returns 0.
89 *----------------------------------------------------------------------------*/
91 flag
float64_is_signaling_nan( float64 a
)
95 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
96 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
100 /*----------------------------------------------------------------------------
101 | Returns the result of converting the double-precision floating-point NaN
102 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
103 | exception is raised.
104 *----------------------------------------------------------------------------*/
106 static commonNaNT
float64ToCommonNaN( float64 a
)
110 if ( float64_is_signaling_nan( a
) ) float_raise( float_flag_invalid
);
118 /*----------------------------------------------------------------------------
119 | Returns the result of converting the canonical NaN `a' to the double-
120 | precision floating-point format.
121 *----------------------------------------------------------------------------*/
123 static float64
commonNaNToFloat64( commonNaNT a
)
127 ( ( (bits64
) a
.sign
)<<63 )
128 | LIT64( 0x7FF8000000000000 )
133 /*----------------------------------------------------------------------------
134 | Takes two double-precision floating-point values `a' and `b', one of which
135 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
136 | signaling NaN, the invalid exception is raised.
137 *----------------------------------------------------------------------------*/
139 static float64
propagateFloat64NaN( float64 a
, float64 b
)
141 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
143 aIsNaN
= float64_is_nan( a
);
144 aIsSignalingNaN
= float64_is_signaling_nan( a
);
145 bIsNaN
= float64_is_nan( b
);
146 bIsSignalingNaN
= float64_is_signaling_nan( b
);
147 a
|= LIT64( 0x0008000000000000 );
148 b
|= LIT64( 0x0008000000000000 );
149 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid
);
150 if ( aIsSignalingNaN
) {
151 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
152 return bIsNaN
? b
: a
;
155 if ( bIsSignalingNaN
| ! bIsNaN
) return a
;
156 returnLargerSignificand
:
157 if ( (bits64
) ( a
<<1 ) < (bits64
) ( b
<<1 ) ) return b
;
158 if ( (bits64
) ( b
<<1 ) < (bits64
) ( a
<<1 ) ) return a
;
159 return ( a
< b
) ? a
: b
;
169 /*----------------------------------------------------------------------------
170 | The pattern for a default generated extended double-precision NaN. The
171 | `high' and `low' values hold the most- and least-significant bits,
173 *----------------------------------------------------------------------------*/
174 #define floatx80_default_nan_high 0xFFFF
175 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
177 /*----------------------------------------------------------------------------
178 | Returns 1 if the extended double-precision floating-point value `a' is a
179 | NaN; otherwise, returns 0.
180 *----------------------------------------------------------------------------*/
182 flag
floatx80_is_nan( floatx80 a
)
185 return ( ( a
.high
& 0x7FFF ) == 0x7FFF ) && (bits64
) ( a
.low
<<1 );
189 /*----------------------------------------------------------------------------
190 | Returns 1 if the extended double-precision floating-point value `a' is a
191 | signaling NaN; otherwise, returns 0.
192 *----------------------------------------------------------------------------*/
194 flag
floatx80_is_signaling_nan( floatx80 a
)
198 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
200 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
201 && (bits64
) ( aLow
<<1 )
202 && ( a
.low
== aLow
);
206 /*----------------------------------------------------------------------------
207 | Returns the result of converting the extended double-precision floating-
208 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
209 | invalid exception is raised.
210 *----------------------------------------------------------------------------*/
212 static commonNaNT
floatx80ToCommonNaN( floatx80 a
)
216 if ( floatx80_is_signaling_nan( a
) ) float_raise( float_flag_invalid
);
224 /*----------------------------------------------------------------------------
225 | Returns the result of converting the canonical NaN `a' to the extended
226 | double-precision floating-point format.
227 *----------------------------------------------------------------------------*/
229 static floatx80
commonNaNToFloatx80( commonNaNT a
)
233 z
.low
= LIT64( 0xC000000000000000 ) | ( a
.high
>>1 );
234 z
.high
= ( ( (bits16
) a
.sign
)<<15 ) | 0x7FFF;
239 /*----------------------------------------------------------------------------
240 | Takes two extended double-precision floating-point values `a' and `b', one
241 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
242 | `b' is a signaling NaN, the invalid exception is raised.
243 *----------------------------------------------------------------------------*/
245 static floatx80
propagateFloatx80NaN( floatx80 a
, floatx80 b
)
247 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
249 aIsNaN
= floatx80_is_nan( a
);
250 aIsSignalingNaN
= floatx80_is_signaling_nan( a
);
251 bIsNaN
= floatx80_is_nan( b
);
252 bIsSignalingNaN
= floatx80_is_signaling_nan( b
);
253 a
.low
|= LIT64( 0xC000000000000000 );
254 b
.low
|= LIT64( 0xC000000000000000 );
255 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid
);
256 if ( aIsSignalingNaN
) {
257 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
258 return bIsNaN
? b
: a
;
261 if ( bIsSignalingNaN
| ! bIsNaN
) return a
;
262 returnLargerSignificand
:
263 if ( a
.low
< b
.low
) return b
;
264 if ( b
.low
< a
.low
) return a
;
265 return ( a
.high
< b
.high
) ? a
: b
;
277 /*----------------------------------------------------------------------------
278 | The pattern for a default generated quadruple-precision NaN. The `high' and
279 | `low' values hold the most- and least-significant bits, respectively.
280 *----------------------------------------------------------------------------*/
281 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
282 #define float128_default_nan_low LIT64( 0x0000000000000000 )
284 /*----------------------------------------------------------------------------
285 | Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
286 | otherwise, returns 0.
287 *----------------------------------------------------------------------------*/
289 flag
float128_is_nan( float128 a
)
293 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
294 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
298 /*----------------------------------------------------------------------------
299 | Returns 1 if the quadruple-precision floating-point value `a' is a
300 | signaling NaN; otherwise, returns 0.
301 *----------------------------------------------------------------------------*/
303 flag
float128_is_signaling_nan( float128 a
)
307 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
308 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
312 /*----------------------------------------------------------------------------
313 | Returns the result of converting the quadruple-precision floating-point NaN
314 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
315 | exception is raised.
316 *----------------------------------------------------------------------------*/
318 static commonNaNT
float128ToCommonNaN( float128 a
)
322 if ( float128_is_signaling_nan( a
) ) float_raise( float_flag_invalid
);
324 shortShift128Left( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
329 /*----------------------------------------------------------------------------
330 | Returns the result of converting the canonical NaN `a' to the quadruple-
331 | precision floating-point format.
332 *----------------------------------------------------------------------------*/
334 static float128
commonNaNToFloat128( commonNaNT a
)
338 shift128Right( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
339 z
.high
|= ( ( (bits64
) a
.sign
)<<63 ) | LIT64( 0x7FFF800000000000 );
344 /*----------------------------------------------------------------------------
345 | Takes two quadruple-precision floating-point values `a' and `b', one of
346 | which is a NaN, and returns the appropriate NaN result. If either `a' or
347 | `b' is a signaling NaN, the invalid exception is raised.
348 *----------------------------------------------------------------------------*/
350 static float128
propagateFloat128NaN( float128 a
, float128 b
)
352 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
354 aIsNaN
= float128_is_nan( a
);
355 aIsSignalingNaN
= float128_is_signaling_nan( a
);
356 bIsNaN
= float128_is_nan( b
);
357 bIsSignalingNaN
= float128_is_signaling_nan( b
);
358 a
.high
|= LIT64( 0x0000800000000000 );
359 b
.high
|= LIT64( 0x0000800000000000 );
360 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid
);
361 if ( aIsSignalingNaN
) {
362 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
363 return bIsNaN
? b
: a
;
366 if ( bIsSignalingNaN
| ! bIsNaN
) return a
;
367 returnLargerSignificand
:
368 if ( lt128( a
.high
<<1, a
.low
, b
.high
<<1, b
.low
) ) return b
;
369 if ( lt128( b
.high
<<1, b
.low
, a
.high
<<1, a
.low
) ) return a
;
370 return ( a
.high
< b
.high
) ? a
: b
;