Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ de4af5f7

History | View | Annotate | Download (26 kB)

1 158142c2 bellard
2 158142c2 bellard
/*============================================================================
3 158142c2 bellard

4 158142c2 bellard
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5 158142c2 bellard
Arithmetic Package, Release 2b.
6 158142c2 bellard

7 158142c2 bellard
Written by John R. Hauser.  This work was made possible in part by the
8 158142c2 bellard
International Computer Science Institute, located at Suite 600, 1947 Center
9 158142c2 bellard
Street, Berkeley, California 94704.  Funding was partially provided by the
10 158142c2 bellard
National Science Foundation under grant MIP-9311980.  The original version
11 158142c2 bellard
of this code was written as part of a project to build a fixed-point vector
12 158142c2 bellard
processor in collaboration with the University of California at Berkeley,
13 158142c2 bellard
overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
14 158142c2 bellard
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
15 158142c2 bellard
arithmetic/SoftFloat.html'.
16 158142c2 bellard

17 158142c2 bellard
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
18 158142c2 bellard
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
19 158142c2 bellard
RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
20 158142c2 bellard
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
21 158142c2 bellard
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
22 158142c2 bellard
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
23 158142c2 bellard
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
24 158142c2 bellard
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
25 158142c2 bellard

26 158142c2 bellard
Derivative works are acceptable, even for commercial purposes, so long as
27 158142c2 bellard
(1) the source code for the derivative work includes prominent notice that
28 158142c2 bellard
the work is derivative, and (2) the source code includes prominent notice with
29 158142c2 bellard
these four paragraphs for those parts of this code that are retained.
30 158142c2 bellard

31 158142c2 bellard
=============================================================================*/
32 158142c2 bellard
33 e9087750 Aurelien Jarno
#if defined(TARGET_MIPS) || defined(TARGET_SH4)
34 5a6932d5 ths
#define SNAN_BIT_IS_ONE                1
35 5a6932d5 ths
#else
36 5a6932d5 ths
#define SNAN_BIT_IS_ONE                0
37 5a6932d5 ths
#endif
38 5a6932d5 ths
39 158142c2 bellard
/*----------------------------------------------------------------------------
40 158142c2 bellard
| Raises the exceptions specified by `flags'.  Floating-point traps can be
41 158142c2 bellard
| defined here if desired.  It is currently not possible for such a trap
42 158142c2 bellard
| to substitute a result value.  If traps are not implemented, this routine
43 158142c2 bellard
| should be simply `float_exception_flags |= flags;'.
44 158142c2 bellard
*----------------------------------------------------------------------------*/
45 158142c2 bellard
46 158142c2 bellard
void float_raise( int8 flags STATUS_PARAM )
47 158142c2 bellard
{
48 158142c2 bellard
    STATUS(float_exception_flags) |= flags;
49 158142c2 bellard
}
50 158142c2 bellard
51 158142c2 bellard
/*----------------------------------------------------------------------------
52 158142c2 bellard
| Internal canonical NaN format.
53 158142c2 bellard
*----------------------------------------------------------------------------*/
54 158142c2 bellard
typedef struct {
55 158142c2 bellard
    flag sign;
56 158142c2 bellard
    bits64 high, low;
57 158142c2 bellard
} commonNaNT;
58 158142c2 bellard
59 158142c2 bellard
/*----------------------------------------------------------------------------
60 158142c2 bellard
| The pattern for a default generated single-precision NaN.
61 158142c2 bellard
*----------------------------------------------------------------------------*/
62 85016c98 ths
#if defined(TARGET_SPARC)
63 85016c98 ths
#define float32_default_nan make_float32(0x7FFFFFFF)
64 e024e881 Aurelien Jarno
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
65 85016c98 ths
#define float32_default_nan make_float32(0x7FC00000)
66 85016c98 ths
#elif SNAN_BIT_IS_ONE
67 f090c9d4 pbrook
#define float32_default_nan make_float32(0x7FBFFFFF)
68 b645bb48 ths
#else
69 f090c9d4 pbrook
#define float32_default_nan make_float32(0xFFC00000)
70 b645bb48 ths
#endif
71 158142c2 bellard
72 158142c2 bellard
/*----------------------------------------------------------------------------
73 5a6932d5 ths
| Returns 1 if the single-precision floating-point value `a' is a quiet
74 5a6932d5 ths
| NaN; otherwise returns 0.
75 158142c2 bellard
*----------------------------------------------------------------------------*/
76 158142c2 bellard
77 18569871 Peter Maydell
int float32_is_quiet_nan( float32 a_ )
78 158142c2 bellard
{
79 f090c9d4 pbrook
    uint32_t a = float32_val(a_);
80 5a6932d5 ths
#if SNAN_BIT_IS_ONE
81 b645bb48 ths
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
82 b645bb48 ths
#else
83 b645bb48 ths
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
84 b645bb48 ths
#endif
85 158142c2 bellard
}
86 158142c2 bellard
87 158142c2 bellard
/*----------------------------------------------------------------------------
88 158142c2 bellard
| Returns 1 if the single-precision floating-point value `a' is a signaling
89 158142c2 bellard
| NaN; otherwise returns 0.
90 158142c2 bellard
*----------------------------------------------------------------------------*/
91 158142c2 bellard
92 f090c9d4 pbrook
int float32_is_signaling_nan( float32 a_ )
93 158142c2 bellard
{
94 f090c9d4 pbrook
    uint32_t a = float32_val(a_);
95 5a6932d5 ths
#if SNAN_BIT_IS_ONE
96 b645bb48 ths
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
97 b645bb48 ths
#else
98 158142c2 bellard
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
99 b645bb48 ths
#endif
100 158142c2 bellard
}
101 158142c2 bellard
102 158142c2 bellard
/*----------------------------------------------------------------------------
103 b408dbde Peter Maydell
| Returns a quiet NaN if the single-precision floating point value `a' is a
104 b408dbde Peter Maydell
| signaling NaN; otherwise returns `a'.
105 b408dbde Peter Maydell
*----------------------------------------------------------------------------*/
106 b408dbde Peter Maydell
107 b408dbde Peter Maydell
float32 float32_maybe_silence_nan( float32 a_ )
108 b408dbde Peter Maydell
{
109 b408dbde Peter Maydell
    if (float32_is_signaling_nan(a_)) {
110 b408dbde Peter Maydell
#if SNAN_BIT_IS_ONE
111 e9087750 Aurelien Jarno
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
112 93ae1c6f Aurelien Jarno
        return float32_default_nan;
113 93ae1c6f Aurelien Jarno
#  else
114 93ae1c6f Aurelien Jarno
#    error Rules for silencing a signaling NaN are target-specific
115 93ae1c6f Aurelien Jarno
#  endif
116 b408dbde Peter Maydell
#else
117 93ae1c6f Aurelien Jarno
        bits32 a = float32_val(a_);
118 b408dbde Peter Maydell
        a |= (1 << 22);
119 b408dbde Peter Maydell
        return make_float32(a);
120 93ae1c6f Aurelien Jarno
#endif
121 b408dbde Peter Maydell
    }
122 b408dbde Peter Maydell
    return a_;
123 b408dbde Peter Maydell
}
124 b408dbde Peter Maydell
125 b408dbde Peter Maydell
/*----------------------------------------------------------------------------
126 158142c2 bellard
| Returns the result of converting the single-precision floating-point NaN
127 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
128 158142c2 bellard
| exception is raised.
129 158142c2 bellard
*----------------------------------------------------------------------------*/
130 158142c2 bellard
131 158142c2 bellard
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
132 158142c2 bellard
{
133 158142c2 bellard
    commonNaNT z;
134 158142c2 bellard
135 158142c2 bellard
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
136 f090c9d4 pbrook
    z.sign = float32_val(a)>>31;
137 158142c2 bellard
    z.low = 0;
138 f090c9d4 pbrook
    z.high = ( (bits64) float32_val(a) )<<41;
139 158142c2 bellard
    return z;
140 158142c2 bellard
}
141 158142c2 bellard
142 158142c2 bellard
/*----------------------------------------------------------------------------
143 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the single-
144 158142c2 bellard
| precision floating-point format.
145 158142c2 bellard
*----------------------------------------------------------------------------*/
146 158142c2 bellard
147 158142c2 bellard
static float32 commonNaNToFloat32( commonNaNT a )
148 158142c2 bellard
{
149 85016c98 ths
    bits32 mantissa = a.high>>41;
150 85016c98 ths
    if ( mantissa )
151 85016c98 ths
        return make_float32(
152 85016c98 ths
            ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
153 85016c98 ths
    else
154 85016c98 ths
        return float32_default_nan;
155 158142c2 bellard
}
156 158142c2 bellard
157 158142c2 bellard
/*----------------------------------------------------------------------------
158 354f211b Peter Maydell
| Select which NaN to propagate for a two-input operation.
159 354f211b Peter Maydell
| IEEE754 doesn't specify all the details of this, so the
160 354f211b Peter Maydell
| algorithm is target-specific.
161 354f211b Peter Maydell
| The routine is passed various bits of information about the
162 354f211b Peter Maydell
| two NaNs and should return 0 to select NaN a and 1 for NaN b.
163 354f211b Peter Maydell
| Note that signalling NaNs are always squashed to quiet NaNs
164 1f398e08 Aurelien Jarno
| by the caller, by calling floatXX_maybe_silence_nan() before
165 1f398e08 Aurelien Jarno
| returning them.
166 354f211b Peter Maydell
|
167 354f211b Peter Maydell
| aIsLargerSignificand is only valid if both a and b are NaNs
168 354f211b Peter Maydell
| of some kind, and is true if a has the larger significand,
169 354f211b Peter Maydell
| or if both a and b have the same significand but a is
170 354f211b Peter Maydell
| positive but b is negative. It is only needed for the x87
171 354f211b Peter Maydell
| tie-break rule.
172 354f211b Peter Maydell
*----------------------------------------------------------------------------*/
173 354f211b Peter Maydell
174 011da610 Peter Maydell
#if defined(TARGET_ARM)
175 011da610 Peter Maydell
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
176 011da610 Peter Maydell
                    flag aIsLargerSignificand)
177 011da610 Peter Maydell
{
178 011da610 Peter Maydell
    /* ARM mandated NaN propagation rules: take the first of:
179 011da610 Peter Maydell
     *  1. A if it is signaling
180 011da610 Peter Maydell
     *  2. B if it is signaling
181 011da610 Peter Maydell
     *  3. A (quiet)
182 011da610 Peter Maydell
     *  4. B (quiet)
183 011da610 Peter Maydell
     * A signaling NaN is always quietened before returning it.
184 011da610 Peter Maydell
     */
185 011da610 Peter Maydell
    if (aIsSNaN) {
186 011da610 Peter Maydell
        return 0;
187 011da610 Peter Maydell
    } else if (bIsSNaN) {
188 011da610 Peter Maydell
        return 1;
189 011da610 Peter Maydell
    } else if (aIsQNaN) {
190 011da610 Peter Maydell
        return 0;
191 011da610 Peter Maydell
    } else {
192 011da610 Peter Maydell
        return 1;
193 011da610 Peter Maydell
    }
194 011da610 Peter Maydell
}
195 084d19ba Aurelien Jarno
#elif defined(TARGET_MIPS)
196 084d19ba Aurelien Jarno
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
197 084d19ba Aurelien Jarno
                    flag aIsLargerSignificand)
198 084d19ba Aurelien Jarno
{
199 084d19ba Aurelien Jarno
    /* According to MIPS specifications, if one of the two operands is
200 084d19ba Aurelien Jarno
     * a sNaN, a new qNaN has to be generated. This is done in
201 084d19ba Aurelien Jarno
     * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
202 084d19ba Aurelien Jarno
     * says: "When possible, this QNaN result is one of the operand QNaN
203 084d19ba Aurelien Jarno
     * values." In practice it seems that most implementations choose
204 084d19ba Aurelien Jarno
     * the first operand if both operands are qNaN. In short this gives
205 084d19ba Aurelien Jarno
     * the following rules:
206 084d19ba Aurelien Jarno
     *  1. A if it is signaling
207 084d19ba Aurelien Jarno
     *  2. B if it is signaling
208 084d19ba Aurelien Jarno
     *  3. A (quiet)
209 084d19ba Aurelien Jarno
     *  4. B (quiet)
210 084d19ba Aurelien Jarno
     * A signaling NaN is always silenced before returning it.
211 084d19ba Aurelien Jarno
     */
212 084d19ba Aurelien Jarno
    if (aIsSNaN) {
213 084d19ba Aurelien Jarno
        return 0;
214 084d19ba Aurelien Jarno
    } else if (bIsSNaN) {
215 084d19ba Aurelien Jarno
        return 1;
216 084d19ba Aurelien Jarno
    } else if (aIsQNaN) {
217 084d19ba Aurelien Jarno
        return 0;
218 084d19ba Aurelien Jarno
    } else {
219 084d19ba Aurelien Jarno
        return 1;
220 084d19ba Aurelien Jarno
    }
221 084d19ba Aurelien Jarno
}
222 e024e881 Aurelien Jarno
#elif defined(TARGET_PPC)
223 e024e881 Aurelien Jarno
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
224 e024e881 Aurelien Jarno
                   flag aIsLargerSignificand)
225 e024e881 Aurelien Jarno
{
226 e024e881 Aurelien Jarno
    /* PowerPC propagation rules:
227 e024e881 Aurelien Jarno
     *  1. A if it sNaN or qNaN
228 e024e881 Aurelien Jarno
     *  2. B if it sNaN or qNaN
229 e024e881 Aurelien Jarno
     * A signaling NaN is always silenced before returning it.
230 e024e881 Aurelien Jarno
     */
231 e024e881 Aurelien Jarno
    if (aIsSNaN || aIsQNaN) {
232 e024e881 Aurelien Jarno
        return 0;
233 e024e881 Aurelien Jarno
    } else {
234 e024e881 Aurelien Jarno
        return 1;
235 e024e881 Aurelien Jarno
    }
236 e024e881 Aurelien Jarno
}
237 011da610 Peter Maydell
#else
238 354f211b Peter Maydell
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
239 354f211b Peter Maydell
                    flag aIsLargerSignificand)
240 354f211b Peter Maydell
{
241 354f211b Peter Maydell
    /* This implements x87 NaN propagation rules:
242 354f211b Peter Maydell
     * SNaN + QNaN => return the QNaN
243 354f211b Peter Maydell
     * two SNaNs => return the one with the larger significand, silenced
244 354f211b Peter Maydell
     * two QNaNs => return the one with the larger significand
245 354f211b Peter Maydell
     * SNaN and a non-NaN => return the SNaN, silenced
246 354f211b Peter Maydell
     * QNaN and a non-NaN => return the QNaN
247 354f211b Peter Maydell
     *
248 354f211b Peter Maydell
     * If we get down to comparing significands and they are the same,
249 354f211b Peter Maydell
     * return the NaN with the positive sign bit (if any).
250 354f211b Peter Maydell
     */
251 354f211b Peter Maydell
    if (aIsSNaN) {
252 354f211b Peter Maydell
        if (bIsSNaN) {
253 354f211b Peter Maydell
            return aIsLargerSignificand ? 0 : 1;
254 354f211b Peter Maydell
        }
255 354f211b Peter Maydell
        return bIsQNaN ? 1 : 0;
256 354f211b Peter Maydell
    }
257 354f211b Peter Maydell
    else if (aIsQNaN) {
258 354f211b Peter Maydell
        if (bIsSNaN || !bIsQNaN)
259 354f211b Peter Maydell
            return 0;
260 354f211b Peter Maydell
        else {
261 354f211b Peter Maydell
            return aIsLargerSignificand ? 0 : 1;
262 354f211b Peter Maydell
        }
263 354f211b Peter Maydell
    } else {
264 354f211b Peter Maydell
        return 1;
265 354f211b Peter Maydell
    }
266 354f211b Peter Maydell
}
267 011da610 Peter Maydell
#endif
268 354f211b Peter Maydell
269 354f211b Peter Maydell
/*----------------------------------------------------------------------------
270 158142c2 bellard
| Takes two single-precision floating-point values `a' and `b', one of which
271 158142c2 bellard
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
272 158142c2 bellard
| signaling NaN, the invalid exception is raised.
273 158142c2 bellard
*----------------------------------------------------------------------------*/
274 158142c2 bellard
275 158142c2 bellard
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
276 158142c2 bellard
{
277 d735d695 Aurelien Jarno
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
278 d735d695 Aurelien Jarno
    flag aIsLargerSignificand;
279 1f398e08 Aurelien Jarno
    bits32 av, bv;
280 158142c2 bellard
281 d735d695 Aurelien Jarno
    aIsQuietNaN = float32_is_quiet_nan( a );
282 158142c2 bellard
    aIsSignalingNaN = float32_is_signaling_nan( a );
283 d735d695 Aurelien Jarno
    bIsQuietNaN = float32_is_quiet_nan( b );
284 158142c2 bellard
    bIsSignalingNaN = float32_is_signaling_nan( b );
285 f090c9d4 pbrook
    av = float32_val(a);
286 f090c9d4 pbrook
    bv = float32_val(b);
287 1f398e08 Aurelien Jarno
288 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
289 354f211b Peter Maydell
290 10201602 Aurelien Jarno
    if ( STATUS(default_nan_mode) )
291 10201602 Aurelien Jarno
        return float32_default_nan;
292 10201602 Aurelien Jarno
293 354f211b Peter Maydell
    if ((bits32)(av<<1) < (bits32)(bv<<1)) {
294 354f211b Peter Maydell
        aIsLargerSignificand = 0;
295 354f211b Peter Maydell
    } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
296 354f211b Peter Maydell
        aIsLargerSignificand = 1;
297 354f211b Peter Maydell
    } else {
298 354f211b Peter Maydell
        aIsLargerSignificand = (av < bv) ? 1 : 0;
299 158142c2 bellard
    }
300 354f211b Peter Maydell
301 d735d695 Aurelien Jarno
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
302 354f211b Peter Maydell
                aIsLargerSignificand)) {
303 1f398e08 Aurelien Jarno
        return float32_maybe_silence_nan(b);
304 354f211b Peter Maydell
    } else {
305 1f398e08 Aurelien Jarno
        return float32_maybe_silence_nan(a);
306 158142c2 bellard
    }
307 158142c2 bellard
}
308 158142c2 bellard
309 158142c2 bellard
/*----------------------------------------------------------------------------
310 158142c2 bellard
| The pattern for a default generated double-precision NaN.
311 158142c2 bellard
*----------------------------------------------------------------------------*/
312 85016c98 ths
#if defined(TARGET_SPARC)
313 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
314 e024e881 Aurelien Jarno
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
315 85016c98 ths
#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
316 85016c98 ths
#elif SNAN_BIT_IS_ONE
317 f090c9d4 pbrook
#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
318 b645bb48 ths
#else
319 f090c9d4 pbrook
#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
320 b645bb48 ths
#endif
321 158142c2 bellard
322 158142c2 bellard
/*----------------------------------------------------------------------------
323 5a6932d5 ths
| Returns 1 if the double-precision floating-point value `a' is a quiet
324 5a6932d5 ths
| NaN; otherwise returns 0.
325 158142c2 bellard
*----------------------------------------------------------------------------*/
326 158142c2 bellard
327 18569871 Peter Maydell
int float64_is_quiet_nan( float64 a_ )
328 158142c2 bellard
{
329 f090c9d4 pbrook
    bits64 a = float64_val(a_);
330 5a6932d5 ths
#if SNAN_BIT_IS_ONE
331 b645bb48 ths
    return
332 b645bb48 ths
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
333 b645bb48 ths
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
334 b645bb48 ths
#else
335 b645bb48 ths
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
336 b645bb48 ths
#endif
337 158142c2 bellard
}
338 158142c2 bellard
339 158142c2 bellard
/*----------------------------------------------------------------------------
340 158142c2 bellard
| Returns 1 if the double-precision floating-point value `a' is a signaling
341 158142c2 bellard
| NaN; otherwise returns 0.
342 158142c2 bellard
*----------------------------------------------------------------------------*/
343 158142c2 bellard
344 f090c9d4 pbrook
int float64_is_signaling_nan( float64 a_ )
345 158142c2 bellard
{
346 f090c9d4 pbrook
    bits64 a = float64_val(a_);
347 5a6932d5 ths
#if SNAN_BIT_IS_ONE
348 b645bb48 ths
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
349 b645bb48 ths
#else
350 158142c2 bellard
    return
351 158142c2 bellard
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
352 158142c2 bellard
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
353 b645bb48 ths
#endif
354 158142c2 bellard
}
355 158142c2 bellard
356 158142c2 bellard
/*----------------------------------------------------------------------------
357 b408dbde Peter Maydell
| Returns a quiet NaN if the double-precision floating point value `a' is a
358 b408dbde Peter Maydell
| signaling NaN; otherwise returns `a'.
359 b408dbde Peter Maydell
*----------------------------------------------------------------------------*/
360 b408dbde Peter Maydell
361 b408dbde Peter Maydell
float64 float64_maybe_silence_nan( float64 a_ )
362 b408dbde Peter Maydell
{
363 b408dbde Peter Maydell
    if (float64_is_signaling_nan(a_)) {
364 b408dbde Peter Maydell
#if SNAN_BIT_IS_ONE
365 e9087750 Aurelien Jarno
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
366 93ae1c6f Aurelien Jarno
        return float64_default_nan;
367 93ae1c6f Aurelien Jarno
#  else
368 93ae1c6f Aurelien Jarno
#    error Rules for silencing a signaling NaN are target-specific
369 93ae1c6f Aurelien Jarno
#  endif
370 b408dbde Peter Maydell
#else
371 93ae1c6f Aurelien Jarno
        bits64 a = float64_val(a_);
372 b408dbde Peter Maydell
        a |= LIT64( 0x0008000000000000 );
373 b408dbde Peter Maydell
        return make_float64(a);
374 93ae1c6f Aurelien Jarno
#endif
375 b408dbde Peter Maydell
    }
376 b408dbde Peter Maydell
    return a_;
377 b408dbde Peter Maydell
}
378 b408dbde Peter Maydell
379 b408dbde Peter Maydell
/*----------------------------------------------------------------------------
380 158142c2 bellard
| Returns the result of converting the double-precision floating-point NaN
381 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
382 158142c2 bellard
| exception is raised.
383 158142c2 bellard
*----------------------------------------------------------------------------*/
384 158142c2 bellard
385 158142c2 bellard
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
386 158142c2 bellard
{
387 158142c2 bellard
    commonNaNT z;
388 158142c2 bellard
389 158142c2 bellard
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
390 f090c9d4 pbrook
    z.sign = float64_val(a)>>63;
391 158142c2 bellard
    z.low = 0;
392 f090c9d4 pbrook
    z.high = float64_val(a)<<12;
393 158142c2 bellard
    return z;
394 158142c2 bellard
}
395 158142c2 bellard
396 158142c2 bellard
/*----------------------------------------------------------------------------
397 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the double-
398 158142c2 bellard
| precision floating-point format.
399 158142c2 bellard
*----------------------------------------------------------------------------*/
400 158142c2 bellard
401 158142c2 bellard
static float64 commonNaNToFloat64( commonNaNT a )
402 158142c2 bellard
{
403 85016c98 ths
    bits64 mantissa = a.high>>12;
404 85016c98 ths
405 85016c98 ths
    if ( mantissa )
406 85016c98 ths
        return make_float64(
407 85016c98 ths
              ( ( (bits64) a.sign )<<63 )
408 85016c98 ths
            | LIT64( 0x7FF0000000000000 )
409 85016c98 ths
            | ( a.high>>12 ));
410 85016c98 ths
    else
411 85016c98 ths
        return float64_default_nan;
412 158142c2 bellard
}
413 158142c2 bellard
414 158142c2 bellard
/*----------------------------------------------------------------------------
415 158142c2 bellard
| Takes two double-precision floating-point values `a' and `b', one of which
416 158142c2 bellard
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
417 158142c2 bellard
| signaling NaN, the invalid exception is raised.
418 158142c2 bellard
*----------------------------------------------------------------------------*/
419 158142c2 bellard
420 158142c2 bellard
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
421 158142c2 bellard
{
422 d735d695 Aurelien Jarno
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
423 d735d695 Aurelien Jarno
    flag aIsLargerSignificand;
424 1f398e08 Aurelien Jarno
    bits64 av, bv;
425 158142c2 bellard
426 d735d695 Aurelien Jarno
    aIsQuietNaN = float64_is_quiet_nan( a );
427 158142c2 bellard
    aIsSignalingNaN = float64_is_signaling_nan( a );
428 d735d695 Aurelien Jarno
    bIsQuietNaN = float64_is_quiet_nan( b );
429 158142c2 bellard
    bIsSignalingNaN = float64_is_signaling_nan( b );
430 f090c9d4 pbrook
    av = float64_val(a);
431 f090c9d4 pbrook
    bv = float64_val(b);
432 1f398e08 Aurelien Jarno
433 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
434 354f211b Peter Maydell
435 10201602 Aurelien Jarno
    if ( STATUS(default_nan_mode) )
436 10201602 Aurelien Jarno
        return float64_default_nan;
437 10201602 Aurelien Jarno
438 354f211b Peter Maydell
    if ((bits64)(av<<1) < (bits64)(bv<<1)) {
439 354f211b Peter Maydell
        aIsLargerSignificand = 0;
440 354f211b Peter Maydell
    } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
441 354f211b Peter Maydell
        aIsLargerSignificand = 1;
442 354f211b Peter Maydell
    } else {
443 354f211b Peter Maydell
        aIsLargerSignificand = (av < bv) ? 1 : 0;
444 158142c2 bellard
    }
445 354f211b Peter Maydell
446 d735d695 Aurelien Jarno
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
447 354f211b Peter Maydell
                aIsLargerSignificand)) {
448 1f398e08 Aurelien Jarno
        return float64_maybe_silence_nan(b);
449 354f211b Peter Maydell
    } else {
450 1f398e08 Aurelien Jarno
        return float64_maybe_silence_nan(a);
451 158142c2 bellard
    }
452 158142c2 bellard
}
453 158142c2 bellard
454 158142c2 bellard
#ifdef FLOATX80
455 158142c2 bellard
456 158142c2 bellard
/*----------------------------------------------------------------------------
457 158142c2 bellard
| The pattern for a default generated extended double-precision NaN.  The
458 158142c2 bellard
| `high' and `low' values hold the most- and least-significant bits,
459 158142c2 bellard
| respectively.
460 158142c2 bellard
*----------------------------------------------------------------------------*/
461 5a6932d5 ths
#if SNAN_BIT_IS_ONE
462 5a6932d5 ths
#define floatx80_default_nan_high 0x7FFF
463 5a6932d5 ths
#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
464 5a6932d5 ths
#else
465 158142c2 bellard
#define floatx80_default_nan_high 0xFFFF
466 158142c2 bellard
#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
467 5a6932d5 ths
#endif
468 158142c2 bellard
469 158142c2 bellard
/*----------------------------------------------------------------------------
470 158142c2 bellard
| Returns 1 if the extended double-precision floating-point value `a' is a
471 de4af5f7 Aurelien Jarno
| quiet NaN; otherwise returns 0. This slightly differs from the same
472 de4af5f7 Aurelien Jarno
| function for other types as floatx80 has an explicit bit.
473 158142c2 bellard
*----------------------------------------------------------------------------*/
474 158142c2 bellard
475 18569871 Peter Maydell
int floatx80_is_quiet_nan( floatx80 a )
476 158142c2 bellard
{
477 5a6932d5 ths
#if SNAN_BIT_IS_ONE
478 5a6932d5 ths
    bits64 aLow;
479 158142c2 bellard
480 5a6932d5 ths
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
481 5a6932d5 ths
    return
482 5a6932d5 ths
           ( ( a.high & 0x7FFF ) == 0x7FFF )
483 5a6932d5 ths
        && (bits64) ( aLow<<1 )
484 5a6932d5 ths
        && ( a.low == aLow );
485 5a6932d5 ths
#else
486 de4af5f7 Aurelien Jarno
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
487 de4af5f7 Aurelien Jarno
        && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
488 5a6932d5 ths
#endif
489 158142c2 bellard
}
490 158142c2 bellard
491 158142c2 bellard
/*----------------------------------------------------------------------------
492 158142c2 bellard
| Returns 1 if the extended double-precision floating-point value `a' is a
493 de4af5f7 Aurelien Jarno
| signaling NaN; otherwise returns 0. This slightly differs from the same
494 de4af5f7 Aurelien Jarno
| function for other types as floatx80 has an explicit bit.
495 158142c2 bellard
*----------------------------------------------------------------------------*/
496 158142c2 bellard
497 750afe93 bellard
int floatx80_is_signaling_nan( floatx80 a )
498 158142c2 bellard
{
499 5a6932d5 ths
#if SNAN_BIT_IS_ONE
500 de4af5f7 Aurelien Jarno
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
501 de4af5f7 Aurelien Jarno
        && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
502 5a6932d5 ths
#else
503 158142c2 bellard
    bits64 aLow;
504 158142c2 bellard
505 158142c2 bellard
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
506 158142c2 bellard
    return
507 158142c2 bellard
           ( ( a.high & 0x7FFF ) == 0x7FFF )
508 158142c2 bellard
        && (bits64) ( aLow<<1 )
509 158142c2 bellard
        && ( a.low == aLow );
510 5a6932d5 ths
#endif
511 158142c2 bellard
}
512 158142c2 bellard
513 158142c2 bellard
/*----------------------------------------------------------------------------
514 f6a7d92a Aurelien Jarno
| Returns a quiet NaN if the extended double-precision floating point value
515 f6a7d92a Aurelien Jarno
| `a' is a signaling NaN; otherwise returns `a'.
516 f6a7d92a Aurelien Jarno
*----------------------------------------------------------------------------*/
517 f6a7d92a Aurelien Jarno
518 f6a7d92a Aurelien Jarno
floatx80 floatx80_maybe_silence_nan( floatx80 a )
519 f6a7d92a Aurelien Jarno
{
520 f6a7d92a Aurelien Jarno
    if (floatx80_is_signaling_nan(a)) {
521 f6a7d92a Aurelien Jarno
#if SNAN_BIT_IS_ONE
522 e9087750 Aurelien Jarno
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
523 f6a7d92a Aurelien Jarno
        a.low = floatx80_default_nan_low;
524 f6a7d92a Aurelien Jarno
        a.high = floatx80_default_nan_high;
525 f6a7d92a Aurelien Jarno
#  else
526 f6a7d92a Aurelien Jarno
#    error Rules for silencing a signaling NaN are target-specific
527 f6a7d92a Aurelien Jarno
#  endif
528 f6a7d92a Aurelien Jarno
#else
529 f6a7d92a Aurelien Jarno
        a.low |= LIT64( 0xC000000000000000 );
530 f6a7d92a Aurelien Jarno
        return a;
531 f6a7d92a Aurelien Jarno
#endif
532 f6a7d92a Aurelien Jarno
    }
533 f6a7d92a Aurelien Jarno
    return a;
534 f6a7d92a Aurelien Jarno
}
535 f6a7d92a Aurelien Jarno
536 f6a7d92a Aurelien Jarno
/*----------------------------------------------------------------------------
537 158142c2 bellard
| Returns the result of converting the extended double-precision floating-
538 158142c2 bellard
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
539 158142c2 bellard
| invalid exception is raised.
540 158142c2 bellard
*----------------------------------------------------------------------------*/
541 158142c2 bellard
542 158142c2 bellard
static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
543 158142c2 bellard
{
544 158142c2 bellard
    commonNaNT z;
545 158142c2 bellard
546 158142c2 bellard
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
547 158142c2 bellard
    z.sign = a.high>>15;
548 158142c2 bellard
    z.low = 0;
549 85016c98 ths
    z.high = a.low;
550 158142c2 bellard
    return z;
551 158142c2 bellard
}
552 158142c2 bellard
553 158142c2 bellard
/*----------------------------------------------------------------------------
554 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the extended
555 158142c2 bellard
| double-precision floating-point format.
556 158142c2 bellard
*----------------------------------------------------------------------------*/
557 158142c2 bellard
558 158142c2 bellard
static floatx80 commonNaNToFloatx80( commonNaNT a )
559 158142c2 bellard
{
560 158142c2 bellard
    floatx80 z;
561 158142c2 bellard
562 85016c98 ths
    if (a.high)
563 85016c98 ths
        z.low = a.high;
564 85016c98 ths
    else
565 85016c98 ths
        z.low = floatx80_default_nan_low;
566 158142c2 bellard
    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
567 158142c2 bellard
    return z;
568 158142c2 bellard
}
569 158142c2 bellard
570 158142c2 bellard
/*----------------------------------------------------------------------------
571 158142c2 bellard
| Takes two extended double-precision floating-point values `a' and `b', one
572 158142c2 bellard
| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
573 158142c2 bellard
| `b' is a signaling NaN, the invalid exception is raised.
574 158142c2 bellard
*----------------------------------------------------------------------------*/
575 158142c2 bellard
576 158142c2 bellard
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
577 158142c2 bellard
{
578 d735d695 Aurelien Jarno
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
579 d735d695 Aurelien Jarno
    flag aIsLargerSignificand;
580 158142c2 bellard
581 d735d695 Aurelien Jarno
    aIsQuietNaN = floatx80_is_quiet_nan( a );
582 158142c2 bellard
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
583 d735d695 Aurelien Jarno
    bIsQuietNaN = floatx80_is_quiet_nan( b );
584 158142c2 bellard
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
585 1f398e08 Aurelien Jarno
586 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
587 354f211b Peter Maydell
588 10201602 Aurelien Jarno
    if ( STATUS(default_nan_mode) ) {
589 10201602 Aurelien Jarno
        a.low = floatx80_default_nan_low;
590 10201602 Aurelien Jarno
        a.high = floatx80_default_nan_high;
591 10201602 Aurelien Jarno
        return a;
592 10201602 Aurelien Jarno
    }
593 10201602 Aurelien Jarno
594 354f211b Peter Maydell
    if (a.low < b.low) {
595 354f211b Peter Maydell
        aIsLargerSignificand = 0;
596 354f211b Peter Maydell
    } else if (b.low < a.low) {
597 354f211b Peter Maydell
        aIsLargerSignificand = 1;
598 354f211b Peter Maydell
    } else {
599 354f211b Peter Maydell
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
600 158142c2 bellard
    }
601 354f211b Peter Maydell
602 d735d695 Aurelien Jarno
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
603 354f211b Peter Maydell
                aIsLargerSignificand)) {
604 1f398e08 Aurelien Jarno
        return floatx80_maybe_silence_nan(b);
605 354f211b Peter Maydell
    } else {
606 1f398e08 Aurelien Jarno
        return floatx80_maybe_silence_nan(a);
607 158142c2 bellard
    }
608 158142c2 bellard
}
609 158142c2 bellard
610 158142c2 bellard
#endif
611 158142c2 bellard
612 158142c2 bellard
#ifdef FLOAT128
613 158142c2 bellard
614 158142c2 bellard
/*----------------------------------------------------------------------------
615 158142c2 bellard
| The pattern for a default generated quadruple-precision NaN.  The `high' and
616 158142c2 bellard
| `low' values hold the most- and least-significant bits, respectively.
617 158142c2 bellard
*----------------------------------------------------------------------------*/
618 5a6932d5 ths
#if SNAN_BIT_IS_ONE
619 5a6932d5 ths
#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
620 5a6932d5 ths
#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
621 5a6932d5 ths
#else
622 158142c2 bellard
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
623 158142c2 bellard
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
624 5a6932d5 ths
#endif
625 158142c2 bellard
626 158142c2 bellard
/*----------------------------------------------------------------------------
627 5a6932d5 ths
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
628 5a6932d5 ths
| NaN; otherwise returns 0.
629 158142c2 bellard
*----------------------------------------------------------------------------*/
630 158142c2 bellard
631 18569871 Peter Maydell
int float128_is_quiet_nan( float128 a )
632 158142c2 bellard
{
633 5a6932d5 ths
#if SNAN_BIT_IS_ONE
634 5a6932d5 ths
    return
635 5a6932d5 ths
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
636 5a6932d5 ths
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
637 5a6932d5 ths
#else
638 158142c2 bellard
    return
639 158142c2 bellard
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
640 158142c2 bellard
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
641 5a6932d5 ths
#endif
642 158142c2 bellard
}
643 158142c2 bellard
644 158142c2 bellard
/*----------------------------------------------------------------------------
645 158142c2 bellard
| Returns 1 if the quadruple-precision floating-point value `a' is a
646 158142c2 bellard
| signaling NaN; otherwise returns 0.
647 158142c2 bellard
*----------------------------------------------------------------------------*/
648 158142c2 bellard
649 750afe93 bellard
int float128_is_signaling_nan( float128 a )
650 158142c2 bellard
{
651 5a6932d5 ths
#if SNAN_BIT_IS_ONE
652 5a6932d5 ths
    return
653 5a6932d5 ths
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
654 5a6932d5 ths
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
655 5a6932d5 ths
#else
656 158142c2 bellard
    return
657 158142c2 bellard
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
658 158142c2 bellard
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
659 5a6932d5 ths
#endif
660 158142c2 bellard
}
661 158142c2 bellard
662 158142c2 bellard
/*----------------------------------------------------------------------------
663 f6a7d92a Aurelien Jarno
| Returns a quiet NaN if the quadruple-precision floating point value `a' is
664 f6a7d92a Aurelien Jarno
| a signaling NaN; otherwise returns `a'.
665 f6a7d92a Aurelien Jarno
*----------------------------------------------------------------------------*/
666 f6a7d92a Aurelien Jarno
667 f6a7d92a Aurelien Jarno
float128 float128_maybe_silence_nan( float128 a )
668 f6a7d92a Aurelien Jarno
{
669 f6a7d92a Aurelien Jarno
    if (float128_is_signaling_nan(a)) {
670 f6a7d92a Aurelien Jarno
#if SNAN_BIT_IS_ONE
671 e9087750 Aurelien Jarno
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
672 f6a7d92a Aurelien Jarno
        a.low = float128_default_nan_low;
673 f6a7d92a Aurelien Jarno
        a.high = float128_default_nan_high;
674 f6a7d92a Aurelien Jarno
#  else
675 f6a7d92a Aurelien Jarno
#    error Rules for silencing a signaling NaN are target-specific
676 f6a7d92a Aurelien Jarno
#  endif
677 f6a7d92a Aurelien Jarno
#else
678 f6a7d92a Aurelien Jarno
        a.high |= LIT64( 0x0000800000000000 );
679 f6a7d92a Aurelien Jarno
        return a;
680 f6a7d92a Aurelien Jarno
#endif
681 f6a7d92a Aurelien Jarno
    }
682 f6a7d92a Aurelien Jarno
    return a;
683 f6a7d92a Aurelien Jarno
}
684 f6a7d92a Aurelien Jarno
685 f6a7d92a Aurelien Jarno
/*----------------------------------------------------------------------------
686 158142c2 bellard
| Returns the result of converting the quadruple-precision floating-point NaN
687 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
688 158142c2 bellard
| exception is raised.
689 158142c2 bellard
*----------------------------------------------------------------------------*/
690 158142c2 bellard
691 158142c2 bellard
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
692 158142c2 bellard
{
693 158142c2 bellard
    commonNaNT z;
694 158142c2 bellard
695 158142c2 bellard
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
696 158142c2 bellard
    z.sign = a.high>>63;
697 158142c2 bellard
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
698 158142c2 bellard
    return z;
699 158142c2 bellard
}
700 158142c2 bellard
701 158142c2 bellard
/*----------------------------------------------------------------------------
702 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the quadruple-
703 158142c2 bellard
| precision floating-point format.
704 158142c2 bellard
*----------------------------------------------------------------------------*/
705 158142c2 bellard
706 158142c2 bellard
static float128 commonNaNToFloat128( commonNaNT a )
707 158142c2 bellard
{
708 158142c2 bellard
    float128 z;
709 158142c2 bellard
710 158142c2 bellard
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
711 85016c98 ths
    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
712 158142c2 bellard
    return z;
713 158142c2 bellard
}
714 158142c2 bellard
715 158142c2 bellard
/*----------------------------------------------------------------------------
716 158142c2 bellard
| Takes two quadruple-precision floating-point values `a' and `b', one of
717 158142c2 bellard
| which is a NaN, and returns the appropriate NaN result.  If either `a' or
718 158142c2 bellard
| `b' is a signaling NaN, the invalid exception is raised.
719 158142c2 bellard
*----------------------------------------------------------------------------*/
720 158142c2 bellard
721 158142c2 bellard
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
722 158142c2 bellard
{
723 d735d695 Aurelien Jarno
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
724 d735d695 Aurelien Jarno
    flag aIsLargerSignificand;
725 158142c2 bellard
726 d735d695 Aurelien Jarno
    aIsQuietNaN = float128_is_quiet_nan( a );
727 158142c2 bellard
    aIsSignalingNaN = float128_is_signaling_nan( a );
728 d735d695 Aurelien Jarno
    bIsQuietNaN = float128_is_quiet_nan( b );
729 158142c2 bellard
    bIsSignalingNaN = float128_is_signaling_nan( b );
730 1f398e08 Aurelien Jarno
731 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
732 354f211b Peter Maydell
733 10201602 Aurelien Jarno
    if ( STATUS(default_nan_mode) ) {
734 10201602 Aurelien Jarno
        a.low = float128_default_nan_low;
735 10201602 Aurelien Jarno
        a.high = float128_default_nan_high;
736 10201602 Aurelien Jarno
        return a;
737 10201602 Aurelien Jarno
    }
738 10201602 Aurelien Jarno
739 354f211b Peter Maydell
    if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
740 354f211b Peter Maydell
        aIsLargerSignificand = 0;
741 354f211b Peter Maydell
    } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
742 354f211b Peter Maydell
        aIsLargerSignificand = 1;
743 354f211b Peter Maydell
    } else {
744 354f211b Peter Maydell
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
745 158142c2 bellard
    }
746 354f211b Peter Maydell
747 d735d695 Aurelien Jarno
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
748 354f211b Peter Maydell
                aIsLargerSignificand)) {
749 1f398e08 Aurelien Jarno
        return float128_maybe_silence_nan(b);
750 354f211b Peter Maydell
    } else {
751 1f398e08 Aurelien Jarno
        return float128_maybe_silence_nan(a);
752 158142c2 bellard
    }
753 158142c2 bellard
}
754 158142c2 bellard
755 158142c2 bellard
#endif