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