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