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