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