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