Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ 19bf7c87

History | View | Annotate | Download (36.6 kB)

1 8d725fac Andreas Färber
/*
2 8d725fac Andreas Färber
 * QEMU float support
3 8d725fac Andreas Färber
 *
4 8d725fac Andreas Färber
 * Derived from SoftFloat.
5 8d725fac Andreas Färber
 */
6 158142c2 bellard
7 158142c2 bellard
/*============================================================================
8 158142c2 bellard

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

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

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

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

36 158142c2 bellard
=============================================================================*/
37 158142c2 bellard
38 789ec7ce Paolo Bonzini
#if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
39 789ec7ce Paolo Bonzini
#define SNAN_BIT_IS_ONE                1
40 789ec7ce Paolo Bonzini
#else
41 789ec7ce Paolo Bonzini
#define SNAN_BIT_IS_ONE                0
42 789ec7ce Paolo Bonzini
#endif
43 789ec7ce Paolo Bonzini
44 789ec7ce Paolo Bonzini
/*----------------------------------------------------------------------------
45 789ec7ce Paolo Bonzini
| The pattern for a default generated half-precision NaN.
46 789ec7ce Paolo Bonzini
*----------------------------------------------------------------------------*/
47 789ec7ce Paolo Bonzini
#if defined(TARGET_ARM)
48 789ec7ce Paolo Bonzini
const float16 float16_default_nan = const_float16(0x7E00);
49 789ec7ce Paolo Bonzini
#elif SNAN_BIT_IS_ONE
50 789ec7ce Paolo Bonzini
const float16 float16_default_nan = const_float16(0x7DFF);
51 789ec7ce Paolo Bonzini
#else
52 789ec7ce Paolo Bonzini
const float16 float16_default_nan = const_float16(0xFE00);
53 789ec7ce Paolo Bonzini
#endif
54 789ec7ce Paolo Bonzini
55 789ec7ce Paolo Bonzini
/*----------------------------------------------------------------------------
56 789ec7ce Paolo Bonzini
| The pattern for a default generated single-precision NaN.
57 789ec7ce Paolo Bonzini
*----------------------------------------------------------------------------*/
58 789ec7ce Paolo Bonzini
#if defined(TARGET_SPARC)
59 789ec7ce Paolo Bonzini
const float32 float32_default_nan = const_float32(0x7FFFFFFF);
60 789ec7ce Paolo Bonzini
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
61 789ec7ce Paolo Bonzini
const float32 float32_default_nan = const_float32(0x7FC00000);
62 789ec7ce Paolo Bonzini
#elif SNAN_BIT_IS_ONE
63 789ec7ce Paolo Bonzini
const float32 float32_default_nan = const_float32(0x7FBFFFFF);
64 789ec7ce Paolo Bonzini
#else
65 789ec7ce Paolo Bonzini
const float32 float32_default_nan = const_float32(0xFFC00000);
66 789ec7ce Paolo Bonzini
#endif
67 789ec7ce Paolo Bonzini
68 789ec7ce Paolo Bonzini
/*----------------------------------------------------------------------------
69 789ec7ce Paolo Bonzini
| The pattern for a default generated double-precision NaN.
70 789ec7ce Paolo Bonzini
*----------------------------------------------------------------------------*/
71 789ec7ce Paolo Bonzini
#if defined(TARGET_SPARC)
72 789ec7ce Paolo Bonzini
const float64 float64_default_nan = const_float64(LIT64( 0x7FFFFFFFFFFFFFFF ));
73 789ec7ce Paolo Bonzini
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
74 789ec7ce Paolo Bonzini
const float64 float64_default_nan = const_float64(LIT64( 0x7FF8000000000000 ));
75 789ec7ce Paolo Bonzini
#elif SNAN_BIT_IS_ONE
76 789ec7ce Paolo Bonzini
const float64 float64_default_nan = const_float64(LIT64( 0x7FF7FFFFFFFFFFFF ));
77 789ec7ce Paolo Bonzini
#else
78 789ec7ce Paolo Bonzini
const float64 float64_default_nan = const_float64(LIT64( 0xFFF8000000000000 ));
79 789ec7ce Paolo Bonzini
#endif
80 789ec7ce Paolo Bonzini
81 789ec7ce Paolo Bonzini
/*----------------------------------------------------------------------------
82 789ec7ce Paolo Bonzini
| The pattern for a default generated extended double-precision NaN.
83 789ec7ce Paolo Bonzini
*----------------------------------------------------------------------------*/
84 789ec7ce Paolo Bonzini
#if SNAN_BIT_IS_ONE
85 789ec7ce Paolo Bonzini
#define floatx80_default_nan_high 0x7FFF
86 789ec7ce Paolo Bonzini
#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
87 789ec7ce Paolo Bonzini
#else
88 789ec7ce Paolo Bonzini
#define floatx80_default_nan_high 0xFFFF
89 789ec7ce Paolo Bonzini
#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
90 789ec7ce Paolo Bonzini
#endif
91 789ec7ce Paolo Bonzini
92 789ec7ce Paolo Bonzini
const floatx80 floatx80_default_nan = make_floatx80(floatx80_default_nan_high,
93 789ec7ce Paolo Bonzini
                                                    floatx80_default_nan_low);
94 789ec7ce Paolo Bonzini
95 789ec7ce Paolo Bonzini
/*----------------------------------------------------------------------------
96 789ec7ce Paolo Bonzini
| The pattern for a default generated quadruple-precision NaN.  The `high' and
97 789ec7ce Paolo Bonzini
| `low' values hold the most- and least-significant bits, respectively.
98 789ec7ce Paolo Bonzini
*----------------------------------------------------------------------------*/
99 789ec7ce Paolo Bonzini
#if SNAN_BIT_IS_ONE
100 789ec7ce Paolo Bonzini
#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
101 789ec7ce Paolo Bonzini
#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
102 789ec7ce Paolo Bonzini
#else
103 789ec7ce Paolo Bonzini
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
104 789ec7ce Paolo Bonzini
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
105 789ec7ce Paolo Bonzini
#endif
106 789ec7ce Paolo Bonzini
107 789ec7ce Paolo Bonzini
const float128 float128_default_nan = make_float128(float128_default_nan_high,
108 789ec7ce Paolo Bonzini
                                                    float128_default_nan_low);
109 789ec7ce Paolo Bonzini
110 158142c2 bellard
/*----------------------------------------------------------------------------
111 158142c2 bellard
| Raises the exceptions specified by `flags'.  Floating-point traps can be
112 158142c2 bellard
| defined here if desired.  It is currently not possible for such a trap
113 158142c2 bellard
| to substitute a result value.  If traps are not implemented, this routine
114 158142c2 bellard
| should be simply `float_exception_flags |= flags;'.
115 158142c2 bellard
*----------------------------------------------------------------------------*/
116 158142c2 bellard
117 158142c2 bellard
void float_raise( int8 flags STATUS_PARAM )
118 158142c2 bellard
{
119 158142c2 bellard
    STATUS(float_exception_flags) |= flags;
120 158142c2 bellard
}
121 158142c2 bellard
122 158142c2 bellard
/*----------------------------------------------------------------------------
123 158142c2 bellard
| Internal canonical NaN format.
124 158142c2 bellard
*----------------------------------------------------------------------------*/
125 158142c2 bellard
typedef struct {
126 158142c2 bellard
    flag sign;
127 bb98fe42 Andreas Färber
    uint64_t high, low;
128 158142c2 bellard
} commonNaNT;
129 158142c2 bellard
130 158142c2 bellard
/*----------------------------------------------------------------------------
131 bb4d4bb3 Peter Maydell
| Returns 1 if the half-precision floating-point value `a' is a quiet
132 bb4d4bb3 Peter Maydell
| NaN; otherwise returns 0.
133 bb4d4bb3 Peter Maydell
*----------------------------------------------------------------------------*/
134 bb4d4bb3 Peter Maydell
135 bb4d4bb3 Peter Maydell
int float16_is_quiet_nan(float16 a_)
136 bb4d4bb3 Peter Maydell
{
137 bb4d4bb3 Peter Maydell
    uint16_t a = float16_val(a_);
138 bb4d4bb3 Peter Maydell
#if SNAN_BIT_IS_ONE
139 bb4d4bb3 Peter Maydell
    return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
140 bb4d4bb3 Peter Maydell
#else
141 bb4d4bb3 Peter Maydell
    return ((a & ~0x8000) >= 0x7c80);
142 bb4d4bb3 Peter Maydell
#endif
143 bb4d4bb3 Peter Maydell
}
144 bb4d4bb3 Peter Maydell
145 bb4d4bb3 Peter Maydell
/*----------------------------------------------------------------------------
146 bb4d4bb3 Peter Maydell
| Returns 1 if the half-precision floating-point value `a' is a signaling
147 bb4d4bb3 Peter Maydell
| NaN; otherwise returns 0.
148 bb4d4bb3 Peter Maydell
*----------------------------------------------------------------------------*/
149 bb4d4bb3 Peter Maydell
150 bb4d4bb3 Peter Maydell
int float16_is_signaling_nan(float16 a_)
151 bb4d4bb3 Peter Maydell
{
152 bb4d4bb3 Peter Maydell
    uint16_t a = float16_val(a_);
153 bb4d4bb3 Peter Maydell
#if SNAN_BIT_IS_ONE
154 bb4d4bb3 Peter Maydell
    return ((a & ~0x8000) >= 0x7c80);
155 bb4d4bb3 Peter Maydell
#else
156 bb4d4bb3 Peter Maydell
    return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
157 bb4d4bb3 Peter Maydell
#endif
158 bb4d4bb3 Peter Maydell
}
159 bb4d4bb3 Peter Maydell
160 bb4d4bb3 Peter Maydell
/*----------------------------------------------------------------------------
161 bb4d4bb3 Peter Maydell
| Returns a quiet NaN if the half-precision floating point value `a' is a
162 bb4d4bb3 Peter Maydell
| signaling NaN; otherwise returns `a'.
163 bb4d4bb3 Peter Maydell
*----------------------------------------------------------------------------*/
164 bb4d4bb3 Peter Maydell
float16 float16_maybe_silence_nan(float16 a_)
165 bb4d4bb3 Peter Maydell
{
166 bb4d4bb3 Peter Maydell
    if (float16_is_signaling_nan(a_)) {
167 bb4d4bb3 Peter Maydell
#if SNAN_BIT_IS_ONE
168 d2fbca94 Guan Xuetao
#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
169 bb4d4bb3 Peter Maydell
        return float16_default_nan;
170 bb4d4bb3 Peter Maydell
#  else
171 bb4d4bb3 Peter Maydell
#    error Rules for silencing a signaling NaN are target-specific
172 bb4d4bb3 Peter Maydell
#  endif
173 bb4d4bb3 Peter Maydell
#else
174 bb4d4bb3 Peter Maydell
        uint16_t a = float16_val(a_);
175 bb4d4bb3 Peter Maydell
        a |= (1 << 9);
176 bb4d4bb3 Peter Maydell
        return make_float16(a);
177 bb4d4bb3 Peter Maydell
#endif
178 bb4d4bb3 Peter Maydell
    }
179 bb4d4bb3 Peter Maydell
    return a_;
180 bb4d4bb3 Peter Maydell
}
181 bb4d4bb3 Peter Maydell
182 bb4d4bb3 Peter Maydell
/*----------------------------------------------------------------------------
183 f591e1be Peter Maydell
| Returns the result of converting the half-precision floating-point NaN
184 f591e1be Peter Maydell
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
185 f591e1be Peter Maydell
| exception is raised.
186 f591e1be Peter Maydell
*----------------------------------------------------------------------------*/
187 f591e1be Peter Maydell
188 f591e1be Peter Maydell
static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM )
189 f591e1be Peter Maydell
{
190 f591e1be Peter Maydell
    commonNaNT z;
191 f591e1be Peter Maydell
192 f591e1be Peter Maydell
    if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
193 f591e1be Peter Maydell
    z.sign = float16_val(a) >> 15;
194 f591e1be Peter Maydell
    z.low = 0;
195 bb98fe42 Andreas Färber
    z.high = ((uint64_t) float16_val(a))<<54;
196 f591e1be Peter Maydell
    return z;
197 f591e1be Peter Maydell
}
198 f591e1be Peter Maydell
199 f591e1be Peter Maydell
/*----------------------------------------------------------------------------
200 600e30d2 Peter Maydell
| Returns the result of converting the canonical NaN `a' to the half-
201 600e30d2 Peter Maydell
| precision floating-point format.
202 600e30d2 Peter Maydell
*----------------------------------------------------------------------------*/
203 600e30d2 Peter Maydell
204 600e30d2 Peter Maydell
static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
205 600e30d2 Peter Maydell
{
206 600e30d2 Peter Maydell
    uint16_t mantissa = a.high>>54;
207 600e30d2 Peter Maydell
208 600e30d2 Peter Maydell
    if (STATUS(default_nan_mode)) {
209 600e30d2 Peter Maydell
        return float16_default_nan;
210 600e30d2 Peter Maydell
    }
211 600e30d2 Peter Maydell
212 600e30d2 Peter Maydell
    if (mantissa) {
213 600e30d2 Peter Maydell
        return make_float16(((((uint16_t) a.sign) << 15)
214 600e30d2 Peter Maydell
                             | (0x1F << 10) | mantissa));
215 600e30d2 Peter Maydell
    } else {
216 600e30d2 Peter Maydell
        return float16_default_nan;
217 600e30d2 Peter Maydell
    }
218 600e30d2 Peter Maydell
}
219 600e30d2 Peter Maydell
220 600e30d2 Peter Maydell
/*----------------------------------------------------------------------------
221 5a6932d5 ths
| Returns 1 if the single-precision floating-point value `a' is a quiet
222 5a6932d5 ths
| NaN; otherwise returns 0.
223 158142c2 bellard
*----------------------------------------------------------------------------*/
224 158142c2 bellard
225 18569871 Peter Maydell
int float32_is_quiet_nan( float32 a_ )
226 158142c2 bellard
{
227 f090c9d4 pbrook
    uint32_t a = float32_val(a_);
228 5a6932d5 ths
#if SNAN_BIT_IS_ONE
229 b645bb48 ths
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
230 b645bb48 ths
#else
231 bb98fe42 Andreas Färber
    return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
232 b645bb48 ths
#endif
233 158142c2 bellard
}
234 158142c2 bellard
235 158142c2 bellard
/*----------------------------------------------------------------------------
236 158142c2 bellard
| Returns 1 if the single-precision floating-point value `a' is a signaling
237 158142c2 bellard
| NaN; otherwise returns 0.
238 158142c2 bellard
*----------------------------------------------------------------------------*/
239 158142c2 bellard
240 f090c9d4 pbrook
int float32_is_signaling_nan( float32 a_ )
241 158142c2 bellard
{
242 f090c9d4 pbrook
    uint32_t a = float32_val(a_);
243 5a6932d5 ths
#if SNAN_BIT_IS_ONE
244 bb98fe42 Andreas Färber
    return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
245 b645bb48 ths
#else
246 158142c2 bellard
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
247 b645bb48 ths
#endif
248 158142c2 bellard
}
249 158142c2 bellard
250 158142c2 bellard
/*----------------------------------------------------------------------------
251 b408dbde Peter Maydell
| Returns a quiet NaN if the single-precision floating point value `a' is a
252 b408dbde Peter Maydell
| signaling NaN; otherwise returns `a'.
253 b408dbde Peter Maydell
*----------------------------------------------------------------------------*/
254 b408dbde Peter Maydell
255 b408dbde Peter Maydell
float32 float32_maybe_silence_nan( float32 a_ )
256 b408dbde Peter Maydell
{
257 b408dbde Peter Maydell
    if (float32_is_signaling_nan(a_)) {
258 b408dbde Peter Maydell
#if SNAN_BIT_IS_ONE
259 d2fbca94 Guan Xuetao
#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
260 93ae1c6f Aurelien Jarno
        return float32_default_nan;
261 93ae1c6f Aurelien Jarno
#  else
262 93ae1c6f Aurelien Jarno
#    error Rules for silencing a signaling NaN are target-specific
263 93ae1c6f Aurelien Jarno
#  endif
264 b408dbde Peter Maydell
#else
265 bb98fe42 Andreas Färber
        uint32_t a = float32_val(a_);
266 b408dbde Peter Maydell
        a |= (1 << 22);
267 b408dbde Peter Maydell
        return make_float32(a);
268 93ae1c6f Aurelien Jarno
#endif
269 b408dbde Peter Maydell
    }
270 b408dbde Peter Maydell
    return a_;
271 b408dbde Peter Maydell
}
272 b408dbde Peter Maydell
273 b408dbde Peter Maydell
/*----------------------------------------------------------------------------
274 158142c2 bellard
| Returns the result of converting the single-precision floating-point NaN
275 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
276 158142c2 bellard
| exception is raised.
277 158142c2 bellard
*----------------------------------------------------------------------------*/
278 158142c2 bellard
279 158142c2 bellard
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
280 158142c2 bellard
{
281 158142c2 bellard
    commonNaNT z;
282 158142c2 bellard
283 158142c2 bellard
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
284 f090c9d4 pbrook
    z.sign = float32_val(a)>>31;
285 158142c2 bellard
    z.low = 0;
286 bb98fe42 Andreas Färber
    z.high = ( (uint64_t) float32_val(a) )<<41;
287 158142c2 bellard
    return z;
288 158142c2 bellard
}
289 158142c2 bellard
290 158142c2 bellard
/*----------------------------------------------------------------------------
291 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the single-
292 158142c2 bellard
| precision floating-point format.
293 158142c2 bellard
*----------------------------------------------------------------------------*/
294 158142c2 bellard
295 bcd4d9af Christophe Lyon
static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM)
296 158142c2 bellard
{
297 bb98fe42 Andreas Färber
    uint32_t mantissa = a.high>>41;
298 bcd4d9af Christophe Lyon
299 bcd4d9af Christophe Lyon
    if ( STATUS(default_nan_mode) ) {
300 bcd4d9af Christophe Lyon
        return float32_default_nan;
301 bcd4d9af Christophe Lyon
    }
302 bcd4d9af Christophe Lyon
303 85016c98 ths
    if ( mantissa )
304 85016c98 ths
        return make_float32(
305 bb98fe42 Andreas Färber
            ( ( (uint32_t) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
306 85016c98 ths
    else
307 85016c98 ths
        return float32_default_nan;
308 158142c2 bellard
}
309 158142c2 bellard
310 158142c2 bellard
/*----------------------------------------------------------------------------
311 354f211b Peter Maydell
| Select which NaN to propagate for a two-input operation.
312 354f211b Peter Maydell
| IEEE754 doesn't specify all the details of this, so the
313 354f211b Peter Maydell
| algorithm is target-specific.
314 354f211b Peter Maydell
| The routine is passed various bits of information about the
315 354f211b Peter Maydell
| two NaNs and should return 0 to select NaN a and 1 for NaN b.
316 354f211b Peter Maydell
| Note that signalling NaNs are always squashed to quiet NaNs
317 1f398e08 Aurelien Jarno
| by the caller, by calling floatXX_maybe_silence_nan() before
318 1f398e08 Aurelien Jarno
| returning them.
319 354f211b Peter Maydell
|
320 354f211b Peter Maydell
| aIsLargerSignificand is only valid if both a and b are NaNs
321 354f211b Peter Maydell
| of some kind, and is true if a has the larger significand,
322 354f211b Peter Maydell
| or if both a and b have the same significand but a is
323 354f211b Peter Maydell
| positive but b is negative. It is only needed for the x87
324 354f211b Peter Maydell
| tie-break rule.
325 354f211b Peter Maydell
*----------------------------------------------------------------------------*/
326 354f211b Peter Maydell
327 011da610 Peter Maydell
#if defined(TARGET_ARM)
328 011da610 Peter Maydell
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
329 011da610 Peter Maydell
                    flag aIsLargerSignificand)
330 011da610 Peter Maydell
{
331 011da610 Peter Maydell
    /* ARM mandated NaN propagation rules: take the first of:
332 011da610 Peter Maydell
     *  1. A if it is signaling
333 011da610 Peter Maydell
     *  2. B if it is signaling
334 011da610 Peter Maydell
     *  3. A (quiet)
335 011da610 Peter Maydell
     *  4. B (quiet)
336 011da610 Peter Maydell
     * A signaling NaN is always quietened before returning it.
337 011da610 Peter Maydell
     */
338 011da610 Peter Maydell
    if (aIsSNaN) {
339 011da610 Peter Maydell
        return 0;
340 011da610 Peter Maydell
    } else if (bIsSNaN) {
341 011da610 Peter Maydell
        return 1;
342 011da610 Peter Maydell
    } else if (aIsQNaN) {
343 011da610 Peter Maydell
        return 0;
344 011da610 Peter Maydell
    } else {
345 011da610 Peter Maydell
        return 1;
346 011da610 Peter Maydell
    }
347 011da610 Peter Maydell
}
348 084d19ba Aurelien Jarno
#elif defined(TARGET_MIPS)
349 084d19ba Aurelien Jarno
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
350 084d19ba Aurelien Jarno
                    flag aIsLargerSignificand)
351 084d19ba Aurelien Jarno
{
352 084d19ba Aurelien Jarno
    /* According to MIPS specifications, if one of the two operands is
353 084d19ba Aurelien Jarno
     * a sNaN, a new qNaN has to be generated. This is done in
354 084d19ba Aurelien Jarno
     * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
355 084d19ba Aurelien Jarno
     * says: "When possible, this QNaN result is one of the operand QNaN
356 084d19ba Aurelien Jarno
     * values." In practice it seems that most implementations choose
357 084d19ba Aurelien Jarno
     * the first operand if both operands are qNaN. In short this gives
358 084d19ba Aurelien Jarno
     * the following rules:
359 084d19ba Aurelien Jarno
     *  1. A if it is signaling
360 084d19ba Aurelien Jarno
     *  2. B if it is signaling
361 084d19ba Aurelien Jarno
     *  3. A (quiet)
362 084d19ba Aurelien Jarno
     *  4. B (quiet)
363 084d19ba Aurelien Jarno
     * A signaling NaN is always silenced before returning it.
364 084d19ba Aurelien Jarno
     */
365 084d19ba Aurelien Jarno
    if (aIsSNaN) {
366 084d19ba Aurelien Jarno
        return 0;
367 084d19ba Aurelien Jarno
    } else if (bIsSNaN) {
368 084d19ba Aurelien Jarno
        return 1;
369 084d19ba Aurelien Jarno
    } else if (aIsQNaN) {
370 084d19ba Aurelien Jarno
        return 0;
371 084d19ba Aurelien Jarno
    } else {
372 084d19ba Aurelien Jarno
        return 1;
373 084d19ba Aurelien Jarno
    }
374 084d19ba Aurelien Jarno
}
375 e024e881 Aurelien Jarno
#elif defined(TARGET_PPC)
376 e024e881 Aurelien Jarno
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
377 e024e881 Aurelien Jarno
                   flag aIsLargerSignificand)
378 e024e881 Aurelien Jarno
{
379 e024e881 Aurelien Jarno
    /* PowerPC propagation rules:
380 e024e881 Aurelien Jarno
     *  1. A if it sNaN or qNaN
381 e024e881 Aurelien Jarno
     *  2. B if it sNaN or qNaN
382 e024e881 Aurelien Jarno
     * A signaling NaN is always silenced before returning it.
383 e024e881 Aurelien Jarno
     */
384 e024e881 Aurelien Jarno
    if (aIsSNaN || aIsQNaN) {
385 e024e881 Aurelien Jarno
        return 0;
386 e024e881 Aurelien Jarno
    } else {
387 e024e881 Aurelien Jarno
        return 1;
388 e024e881 Aurelien Jarno
    }
389 e024e881 Aurelien Jarno
}
390 011da610 Peter Maydell
#else
391 354f211b Peter Maydell
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
392 354f211b Peter Maydell
                    flag aIsLargerSignificand)
393 354f211b Peter Maydell
{
394 354f211b Peter Maydell
    /* This implements x87 NaN propagation rules:
395 354f211b Peter Maydell
     * SNaN + QNaN => return the QNaN
396 354f211b Peter Maydell
     * two SNaNs => return the one with the larger significand, silenced
397 354f211b Peter Maydell
     * two QNaNs => return the one with the larger significand
398 354f211b Peter Maydell
     * SNaN and a non-NaN => return the SNaN, silenced
399 354f211b Peter Maydell
     * QNaN and a non-NaN => return the QNaN
400 354f211b Peter Maydell
     *
401 354f211b Peter Maydell
     * If we get down to comparing significands and they are the same,
402 354f211b Peter Maydell
     * return the NaN with the positive sign bit (if any).
403 354f211b Peter Maydell
     */
404 354f211b Peter Maydell
    if (aIsSNaN) {
405 354f211b Peter Maydell
        if (bIsSNaN) {
406 354f211b Peter Maydell
            return aIsLargerSignificand ? 0 : 1;
407 354f211b Peter Maydell
        }
408 354f211b Peter Maydell
        return bIsQNaN ? 1 : 0;
409 354f211b Peter Maydell
    }
410 354f211b Peter Maydell
    else if (aIsQNaN) {
411 354f211b Peter Maydell
        if (bIsSNaN || !bIsQNaN)
412 354f211b Peter Maydell
            return 0;
413 354f211b Peter Maydell
        else {
414 354f211b Peter Maydell
            return aIsLargerSignificand ? 0 : 1;
415 354f211b Peter Maydell
        }
416 354f211b Peter Maydell
    } else {
417 354f211b Peter Maydell
        return 1;
418 354f211b Peter Maydell
    }
419 354f211b Peter Maydell
}
420 011da610 Peter Maydell
#endif
421 354f211b Peter Maydell
422 354f211b Peter Maydell
/*----------------------------------------------------------------------------
423 369be8f6 Peter Maydell
| Select which NaN to propagate for a three-input operation.
424 369be8f6 Peter Maydell
| For the moment we assume that no CPU needs the 'larger significand'
425 369be8f6 Peter Maydell
| information.
426 369be8f6 Peter Maydell
| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
427 369be8f6 Peter Maydell
*----------------------------------------------------------------------------*/
428 369be8f6 Peter Maydell
#if defined(TARGET_ARM)
429 369be8f6 Peter Maydell
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
430 369be8f6 Peter Maydell
                         flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
431 369be8f6 Peter Maydell
{
432 369be8f6 Peter Maydell
    /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
433 369be8f6 Peter Maydell
     * the default NaN
434 369be8f6 Peter Maydell
     */
435 369be8f6 Peter Maydell
    if (infzero && cIsQNaN) {
436 369be8f6 Peter Maydell
        float_raise(float_flag_invalid STATUS_VAR);
437 369be8f6 Peter Maydell
        return 3;
438 369be8f6 Peter Maydell
    }
439 369be8f6 Peter Maydell
440 369be8f6 Peter Maydell
    /* This looks different from the ARM ARM pseudocode, because the ARM ARM
441 369be8f6 Peter Maydell
     * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
442 369be8f6 Peter Maydell
     */
443 369be8f6 Peter Maydell
    if (cIsSNaN) {
444 369be8f6 Peter Maydell
        return 2;
445 369be8f6 Peter Maydell
    } else if (aIsSNaN) {
446 369be8f6 Peter Maydell
        return 0;
447 369be8f6 Peter Maydell
    } else if (bIsSNaN) {
448 369be8f6 Peter Maydell
        return 1;
449 369be8f6 Peter Maydell
    } else if (cIsQNaN) {
450 369be8f6 Peter Maydell
        return 2;
451 369be8f6 Peter Maydell
    } else if (aIsQNaN) {
452 369be8f6 Peter Maydell
        return 0;
453 369be8f6 Peter Maydell
    } else {
454 369be8f6 Peter Maydell
        return 1;
455 369be8f6 Peter Maydell
    }
456 369be8f6 Peter Maydell
}
457 369be8f6 Peter Maydell
#elif defined(TARGET_PPC)
458 369be8f6 Peter Maydell
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
459 369be8f6 Peter Maydell
                         flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
460 369be8f6 Peter Maydell
{
461 369be8f6 Peter Maydell
    /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
462 369be8f6 Peter Maydell
     * to return an input NaN if we have one (ie c) rather than generating
463 369be8f6 Peter Maydell
     * a default NaN
464 369be8f6 Peter Maydell
     */
465 369be8f6 Peter Maydell
    if (infzero) {
466 369be8f6 Peter Maydell
        float_raise(float_flag_invalid STATUS_VAR);
467 369be8f6 Peter Maydell
        return 2;
468 369be8f6 Peter Maydell
    }
469 369be8f6 Peter Maydell
470 369be8f6 Peter Maydell
    /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
471 369be8f6 Peter Maydell
     * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
472 369be8f6 Peter Maydell
     */
473 369be8f6 Peter Maydell
    if (aIsSNaN || aIsQNaN) {
474 369be8f6 Peter Maydell
        return 0;
475 369be8f6 Peter Maydell
    } else if (cIsSNaN || cIsQNaN) {
476 369be8f6 Peter Maydell
        return 2;
477 369be8f6 Peter Maydell
    } else {
478 369be8f6 Peter Maydell
        return 1;
479 369be8f6 Peter Maydell
    }
480 369be8f6 Peter Maydell
}
481 369be8f6 Peter Maydell
#else
482 369be8f6 Peter Maydell
/* A default implementation: prefer a to b to c.
483 369be8f6 Peter Maydell
 * This is unlikely to actually match any real implementation.
484 369be8f6 Peter Maydell
 */
485 369be8f6 Peter Maydell
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
486 369be8f6 Peter Maydell
                         flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
487 369be8f6 Peter Maydell
{
488 369be8f6 Peter Maydell
    if (aIsSNaN || aIsQNaN) {
489 369be8f6 Peter Maydell
        return 0;
490 369be8f6 Peter Maydell
    } else if (bIsSNaN || bIsQNaN) {
491 369be8f6 Peter Maydell
        return 1;
492 369be8f6 Peter Maydell
    } else {
493 369be8f6 Peter Maydell
        return 2;
494 369be8f6 Peter Maydell
    }
495 369be8f6 Peter Maydell
}
496 369be8f6 Peter Maydell
#endif
497 369be8f6 Peter Maydell
498 369be8f6 Peter Maydell
/*----------------------------------------------------------------------------
499 158142c2 bellard
| Takes two single-precision floating-point values `a' and `b', one of which
500 158142c2 bellard
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
501 158142c2 bellard
| signaling NaN, the invalid exception is raised.
502 158142c2 bellard
*----------------------------------------------------------------------------*/
503 158142c2 bellard
504 158142c2 bellard
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
505 158142c2 bellard
{
506 d735d695 Aurelien Jarno
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
507 d735d695 Aurelien Jarno
    flag aIsLargerSignificand;
508 bb98fe42 Andreas Färber
    uint32_t av, bv;
509 158142c2 bellard
510 d735d695 Aurelien Jarno
    aIsQuietNaN = float32_is_quiet_nan( a );
511 158142c2 bellard
    aIsSignalingNaN = float32_is_signaling_nan( a );
512 d735d695 Aurelien Jarno
    bIsQuietNaN = float32_is_quiet_nan( b );
513 158142c2 bellard
    bIsSignalingNaN = float32_is_signaling_nan( b );
514 f090c9d4 pbrook
    av = float32_val(a);
515 f090c9d4 pbrook
    bv = float32_val(b);
516 1f398e08 Aurelien Jarno
517 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
518 354f211b Peter Maydell
519 10201602 Aurelien Jarno
    if ( STATUS(default_nan_mode) )
520 10201602 Aurelien Jarno
        return float32_default_nan;
521 10201602 Aurelien Jarno
522 bb98fe42 Andreas Färber
    if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) {
523 354f211b Peter Maydell
        aIsLargerSignificand = 0;
524 bb98fe42 Andreas Färber
    } else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) {
525 354f211b Peter Maydell
        aIsLargerSignificand = 1;
526 354f211b Peter Maydell
    } else {
527 354f211b Peter Maydell
        aIsLargerSignificand = (av < bv) ? 1 : 0;
528 158142c2 bellard
    }
529 354f211b Peter Maydell
530 d735d695 Aurelien Jarno
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
531 354f211b Peter Maydell
                aIsLargerSignificand)) {
532 1f398e08 Aurelien Jarno
        return float32_maybe_silence_nan(b);
533 354f211b Peter Maydell
    } else {
534 1f398e08 Aurelien Jarno
        return float32_maybe_silence_nan(a);
535 158142c2 bellard
    }
536 158142c2 bellard
}
537 158142c2 bellard
538 158142c2 bellard
/*----------------------------------------------------------------------------
539 369be8f6 Peter Maydell
| Takes three single-precision floating-point values `a', `b' and `c', one of
540 369be8f6 Peter Maydell
| which is a NaN, and returns the appropriate NaN result.  If any of  `a',
541 369be8f6 Peter Maydell
| `b' or `c' is a signaling NaN, the invalid exception is raised.
542 369be8f6 Peter Maydell
| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
543 369be8f6 Peter Maydell
| obviously c is a NaN, and whether to propagate c or some other NaN is
544 369be8f6 Peter Maydell
| implementation defined).
545 369be8f6 Peter Maydell
*----------------------------------------------------------------------------*/
546 369be8f6 Peter Maydell
547 369be8f6 Peter Maydell
static float32 propagateFloat32MulAddNaN(float32 a, float32 b,
548 369be8f6 Peter Maydell
                                         float32 c, flag infzero STATUS_PARAM)
549 369be8f6 Peter Maydell
{
550 369be8f6 Peter Maydell
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
551 369be8f6 Peter Maydell
        cIsQuietNaN, cIsSignalingNaN;
552 369be8f6 Peter Maydell
    int which;
553 369be8f6 Peter Maydell
554 369be8f6 Peter Maydell
    aIsQuietNaN = float32_is_quiet_nan(a);
555 369be8f6 Peter Maydell
    aIsSignalingNaN = float32_is_signaling_nan(a);
556 369be8f6 Peter Maydell
    bIsQuietNaN = float32_is_quiet_nan(b);
557 369be8f6 Peter Maydell
    bIsSignalingNaN = float32_is_signaling_nan(b);
558 369be8f6 Peter Maydell
    cIsQuietNaN = float32_is_quiet_nan(c);
559 369be8f6 Peter Maydell
    cIsSignalingNaN = float32_is_signaling_nan(c);
560 369be8f6 Peter Maydell
561 369be8f6 Peter Maydell
    if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
562 369be8f6 Peter Maydell
        float_raise(float_flag_invalid STATUS_VAR);
563 369be8f6 Peter Maydell
    }
564 369be8f6 Peter Maydell
565 369be8f6 Peter Maydell
    which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
566 369be8f6 Peter Maydell
                          bIsQuietNaN, bIsSignalingNaN,
567 369be8f6 Peter Maydell
                          cIsQuietNaN, cIsSignalingNaN, infzero STATUS_VAR);
568 369be8f6 Peter Maydell
569 369be8f6 Peter Maydell
    if (STATUS(default_nan_mode)) {
570 369be8f6 Peter Maydell
        /* Note that this check is after pickNaNMulAdd so that function
571 369be8f6 Peter Maydell
         * has an opportunity to set the Invalid flag.
572 369be8f6 Peter Maydell
         */
573 369be8f6 Peter Maydell
        return float32_default_nan;
574 369be8f6 Peter Maydell
    }
575 369be8f6 Peter Maydell
576 369be8f6 Peter Maydell
    switch (which) {
577 369be8f6 Peter Maydell
    case 0:
578 369be8f6 Peter Maydell
        return float32_maybe_silence_nan(a);
579 369be8f6 Peter Maydell
    case 1:
580 369be8f6 Peter Maydell
        return float32_maybe_silence_nan(b);
581 369be8f6 Peter Maydell
    case 2:
582 369be8f6 Peter Maydell
        return float32_maybe_silence_nan(c);
583 369be8f6 Peter Maydell
    case 3:
584 369be8f6 Peter Maydell
    default:
585 369be8f6 Peter Maydell
        return float32_default_nan;
586 369be8f6 Peter Maydell
    }
587 369be8f6 Peter Maydell
}
588 369be8f6 Peter Maydell
589 369be8f6 Peter Maydell
/*----------------------------------------------------------------------------
590 5a6932d5 ths
| Returns 1 if the double-precision floating-point value `a' is a quiet
591 5a6932d5 ths
| NaN; otherwise returns 0.
592 158142c2 bellard
*----------------------------------------------------------------------------*/
593 158142c2 bellard
594 18569871 Peter Maydell
int float64_is_quiet_nan( float64 a_ )
595 158142c2 bellard
{
596 bb98fe42 Andreas Färber
    uint64_t a = float64_val(a_);
597 5a6932d5 ths
#if SNAN_BIT_IS_ONE
598 b645bb48 ths
    return
599 b645bb48 ths
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
600 b645bb48 ths
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
601 b645bb48 ths
#else
602 bb98fe42 Andreas Färber
    return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
603 b645bb48 ths
#endif
604 158142c2 bellard
}
605 158142c2 bellard
606 158142c2 bellard
/*----------------------------------------------------------------------------
607 158142c2 bellard
| Returns 1 if the double-precision floating-point value `a' is a signaling
608 158142c2 bellard
| NaN; otherwise returns 0.
609 158142c2 bellard
*----------------------------------------------------------------------------*/
610 158142c2 bellard
611 f090c9d4 pbrook
int float64_is_signaling_nan( float64 a_ )
612 158142c2 bellard
{
613 bb98fe42 Andreas Färber
    uint64_t a = float64_val(a_);
614 5a6932d5 ths
#if SNAN_BIT_IS_ONE
615 bb98fe42 Andreas Färber
    return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
616 b645bb48 ths
#else
617 158142c2 bellard
    return
618 158142c2 bellard
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
619 158142c2 bellard
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
620 b645bb48 ths
#endif
621 158142c2 bellard
}
622 158142c2 bellard
623 158142c2 bellard
/*----------------------------------------------------------------------------
624 b408dbde Peter Maydell
| Returns a quiet NaN if the double-precision floating point value `a' is a
625 b408dbde Peter Maydell
| signaling NaN; otherwise returns `a'.
626 b408dbde Peter Maydell
*----------------------------------------------------------------------------*/
627 b408dbde Peter Maydell
628 b408dbde Peter Maydell
float64 float64_maybe_silence_nan( float64 a_ )
629 b408dbde Peter Maydell
{
630 b408dbde Peter Maydell
    if (float64_is_signaling_nan(a_)) {
631 b408dbde Peter Maydell
#if SNAN_BIT_IS_ONE
632 d2fbca94 Guan Xuetao
#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
633 93ae1c6f Aurelien Jarno
        return float64_default_nan;
634 93ae1c6f Aurelien Jarno
#  else
635 93ae1c6f Aurelien Jarno
#    error Rules for silencing a signaling NaN are target-specific
636 93ae1c6f Aurelien Jarno
#  endif
637 b408dbde Peter Maydell
#else
638 bb98fe42 Andreas Färber
        uint64_t a = float64_val(a_);
639 b408dbde Peter Maydell
        a |= LIT64( 0x0008000000000000 );
640 b408dbde Peter Maydell
        return make_float64(a);
641 93ae1c6f Aurelien Jarno
#endif
642 b408dbde Peter Maydell
    }
643 b408dbde Peter Maydell
    return a_;
644 b408dbde Peter Maydell
}
645 b408dbde Peter Maydell
646 b408dbde Peter Maydell
/*----------------------------------------------------------------------------
647 158142c2 bellard
| Returns the result of converting the double-precision floating-point NaN
648 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
649 158142c2 bellard
| exception is raised.
650 158142c2 bellard
*----------------------------------------------------------------------------*/
651 158142c2 bellard
652 158142c2 bellard
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
653 158142c2 bellard
{
654 158142c2 bellard
    commonNaNT z;
655 158142c2 bellard
656 158142c2 bellard
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
657 f090c9d4 pbrook
    z.sign = float64_val(a)>>63;
658 158142c2 bellard
    z.low = 0;
659 f090c9d4 pbrook
    z.high = float64_val(a)<<12;
660 158142c2 bellard
    return z;
661 158142c2 bellard
}
662 158142c2 bellard
663 158142c2 bellard
/*----------------------------------------------------------------------------
664 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the double-
665 158142c2 bellard
| precision floating-point format.
666 158142c2 bellard
*----------------------------------------------------------------------------*/
667 158142c2 bellard
668 bcd4d9af Christophe Lyon
static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM)
669 158142c2 bellard
{
670 bb98fe42 Andreas Färber
    uint64_t mantissa = a.high>>12;
671 85016c98 ths
672 bcd4d9af Christophe Lyon
    if ( STATUS(default_nan_mode) ) {
673 bcd4d9af Christophe Lyon
        return float64_default_nan;
674 bcd4d9af Christophe Lyon
    }
675 bcd4d9af Christophe Lyon
676 85016c98 ths
    if ( mantissa )
677 85016c98 ths
        return make_float64(
678 bb98fe42 Andreas Färber
              ( ( (uint64_t) a.sign )<<63 )
679 85016c98 ths
            | LIT64( 0x7FF0000000000000 )
680 85016c98 ths
            | ( a.high>>12 ));
681 85016c98 ths
    else
682 85016c98 ths
        return float64_default_nan;
683 158142c2 bellard
}
684 158142c2 bellard
685 158142c2 bellard
/*----------------------------------------------------------------------------
686 158142c2 bellard
| Takes two double-precision floating-point values `a' and `b', one of which
687 158142c2 bellard
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
688 158142c2 bellard
| signaling NaN, the invalid exception is raised.
689 158142c2 bellard
*----------------------------------------------------------------------------*/
690 158142c2 bellard
691 158142c2 bellard
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
692 158142c2 bellard
{
693 d735d695 Aurelien Jarno
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
694 d735d695 Aurelien Jarno
    flag aIsLargerSignificand;
695 bb98fe42 Andreas Färber
    uint64_t av, bv;
696 158142c2 bellard
697 d735d695 Aurelien Jarno
    aIsQuietNaN = float64_is_quiet_nan( a );
698 158142c2 bellard
    aIsSignalingNaN = float64_is_signaling_nan( a );
699 d735d695 Aurelien Jarno
    bIsQuietNaN = float64_is_quiet_nan( b );
700 158142c2 bellard
    bIsSignalingNaN = float64_is_signaling_nan( b );
701 f090c9d4 pbrook
    av = float64_val(a);
702 f090c9d4 pbrook
    bv = float64_val(b);
703 1f398e08 Aurelien Jarno
704 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
705 354f211b Peter Maydell
706 10201602 Aurelien Jarno
    if ( STATUS(default_nan_mode) )
707 10201602 Aurelien Jarno
        return float64_default_nan;
708 10201602 Aurelien Jarno
709 bb98fe42 Andreas Färber
    if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) {
710 354f211b Peter Maydell
        aIsLargerSignificand = 0;
711 bb98fe42 Andreas Färber
    } else if ((uint64_t)(bv<<1) < (uint64_t)(av<<1)) {
712 354f211b Peter Maydell
        aIsLargerSignificand = 1;
713 354f211b Peter Maydell
    } else {
714 354f211b Peter Maydell
        aIsLargerSignificand = (av < bv) ? 1 : 0;
715 158142c2 bellard
    }
716 354f211b Peter Maydell
717 d735d695 Aurelien Jarno
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
718 354f211b Peter Maydell
                aIsLargerSignificand)) {
719 1f398e08 Aurelien Jarno
        return float64_maybe_silence_nan(b);
720 354f211b Peter Maydell
    } else {
721 1f398e08 Aurelien Jarno
        return float64_maybe_silence_nan(a);
722 158142c2 bellard
    }
723 158142c2 bellard
}
724 158142c2 bellard
725 158142c2 bellard
/*----------------------------------------------------------------------------
726 369be8f6 Peter Maydell
| Takes three double-precision floating-point values `a', `b' and `c', one of
727 369be8f6 Peter Maydell
| which is a NaN, and returns the appropriate NaN result.  If any of  `a',
728 369be8f6 Peter Maydell
| `b' or `c' is a signaling NaN, the invalid exception is raised.
729 369be8f6 Peter Maydell
| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
730 369be8f6 Peter Maydell
| obviously c is a NaN, and whether to propagate c or some other NaN is
731 369be8f6 Peter Maydell
| implementation defined).
732 369be8f6 Peter Maydell
*----------------------------------------------------------------------------*/
733 369be8f6 Peter Maydell
734 369be8f6 Peter Maydell
static float64 propagateFloat64MulAddNaN(float64 a, float64 b,
735 369be8f6 Peter Maydell
                                         float64 c, flag infzero STATUS_PARAM)
736 369be8f6 Peter Maydell
{
737 369be8f6 Peter Maydell
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
738 369be8f6 Peter Maydell
        cIsQuietNaN, cIsSignalingNaN;
739 369be8f6 Peter Maydell
    int which;
740 369be8f6 Peter Maydell
741 369be8f6 Peter Maydell
    aIsQuietNaN = float64_is_quiet_nan(a);
742 369be8f6 Peter Maydell
    aIsSignalingNaN = float64_is_signaling_nan(a);
743 369be8f6 Peter Maydell
    bIsQuietNaN = float64_is_quiet_nan(b);
744 369be8f6 Peter Maydell
    bIsSignalingNaN = float64_is_signaling_nan(b);
745 369be8f6 Peter Maydell
    cIsQuietNaN = float64_is_quiet_nan(c);
746 369be8f6 Peter Maydell
    cIsSignalingNaN = float64_is_signaling_nan(c);
747 369be8f6 Peter Maydell
748 369be8f6 Peter Maydell
    if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
749 369be8f6 Peter Maydell
        float_raise(float_flag_invalid STATUS_VAR);
750 369be8f6 Peter Maydell
    }
751 369be8f6 Peter Maydell
752 369be8f6 Peter Maydell
    which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
753 369be8f6 Peter Maydell
                          bIsQuietNaN, bIsSignalingNaN,
754 369be8f6 Peter Maydell
                          cIsQuietNaN, cIsSignalingNaN, infzero STATUS_VAR);
755 369be8f6 Peter Maydell
756 369be8f6 Peter Maydell
    if (STATUS(default_nan_mode)) {
757 369be8f6 Peter Maydell
        /* Note that this check is after pickNaNMulAdd so that function
758 369be8f6 Peter Maydell
         * has an opportunity to set the Invalid flag.
759 369be8f6 Peter Maydell
         */
760 369be8f6 Peter Maydell
        return float64_default_nan;
761 369be8f6 Peter Maydell
    }
762 369be8f6 Peter Maydell
763 369be8f6 Peter Maydell
    switch (which) {
764 369be8f6 Peter Maydell
    case 0:
765 369be8f6 Peter Maydell
        return float64_maybe_silence_nan(a);
766 369be8f6 Peter Maydell
    case 1:
767 369be8f6 Peter Maydell
        return float64_maybe_silence_nan(b);
768 369be8f6 Peter Maydell
    case 2:
769 369be8f6 Peter Maydell
        return float64_maybe_silence_nan(c);
770 369be8f6 Peter Maydell
    case 3:
771 369be8f6 Peter Maydell
    default:
772 369be8f6 Peter Maydell
        return float64_default_nan;
773 369be8f6 Peter Maydell
    }
774 369be8f6 Peter Maydell
}
775 369be8f6 Peter Maydell
776 369be8f6 Peter Maydell
/*----------------------------------------------------------------------------
777 158142c2 bellard
| Returns 1 if the extended double-precision floating-point value `a' is a
778 de4af5f7 Aurelien Jarno
| quiet NaN; otherwise returns 0. This slightly differs from the same
779 de4af5f7 Aurelien Jarno
| function for other types as floatx80 has an explicit bit.
780 158142c2 bellard
*----------------------------------------------------------------------------*/
781 158142c2 bellard
782 18569871 Peter Maydell
int floatx80_is_quiet_nan( floatx80 a )
783 158142c2 bellard
{
784 5a6932d5 ths
#if SNAN_BIT_IS_ONE
785 bb98fe42 Andreas Färber
    uint64_t aLow;
786 158142c2 bellard
787 5a6932d5 ths
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
788 5a6932d5 ths
    return
789 5a6932d5 ths
           ( ( a.high & 0x7FFF ) == 0x7FFF )
790 bb98fe42 Andreas Färber
        && (uint64_t) ( aLow<<1 )
791 5a6932d5 ths
        && ( a.low == aLow );
792 5a6932d5 ths
#else
793 de4af5f7 Aurelien Jarno
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
794 bb98fe42 Andreas Färber
        && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
795 5a6932d5 ths
#endif
796 158142c2 bellard
}
797 158142c2 bellard
798 158142c2 bellard
/*----------------------------------------------------------------------------
799 158142c2 bellard
| Returns 1 if the extended double-precision floating-point value `a' is a
800 de4af5f7 Aurelien Jarno
| signaling NaN; otherwise returns 0. This slightly differs from the same
801 de4af5f7 Aurelien Jarno
| function for other types as floatx80 has an explicit bit.
802 158142c2 bellard
*----------------------------------------------------------------------------*/
803 158142c2 bellard
804 750afe93 bellard
int floatx80_is_signaling_nan( floatx80 a )
805 158142c2 bellard
{
806 5a6932d5 ths
#if SNAN_BIT_IS_ONE
807 de4af5f7 Aurelien Jarno
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
808 bb98fe42 Andreas Färber
        && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
809 5a6932d5 ths
#else
810 bb98fe42 Andreas Färber
    uint64_t aLow;
811 158142c2 bellard
812 158142c2 bellard
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
813 158142c2 bellard
    return
814 158142c2 bellard
           ( ( a.high & 0x7FFF ) == 0x7FFF )
815 bb98fe42 Andreas Färber
        && (uint64_t) ( aLow<<1 )
816 158142c2 bellard
        && ( a.low == aLow );
817 5a6932d5 ths
#endif
818 158142c2 bellard
}
819 158142c2 bellard
820 158142c2 bellard
/*----------------------------------------------------------------------------
821 f6a7d92a Aurelien Jarno
| Returns a quiet NaN if the extended double-precision floating point value
822 f6a7d92a Aurelien Jarno
| `a' is a signaling NaN; otherwise returns `a'.
823 f6a7d92a Aurelien Jarno
*----------------------------------------------------------------------------*/
824 f6a7d92a Aurelien Jarno
825 f6a7d92a Aurelien Jarno
floatx80 floatx80_maybe_silence_nan( floatx80 a )
826 f6a7d92a Aurelien Jarno
{
827 f6a7d92a Aurelien Jarno
    if (floatx80_is_signaling_nan(a)) {
828 f6a7d92a Aurelien Jarno
#if SNAN_BIT_IS_ONE
829 d2fbca94 Guan Xuetao
#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
830 f6a7d92a Aurelien Jarno
        a.low = floatx80_default_nan_low;
831 f6a7d92a Aurelien Jarno
        a.high = floatx80_default_nan_high;
832 f6a7d92a Aurelien Jarno
#  else
833 f6a7d92a Aurelien Jarno
#    error Rules for silencing a signaling NaN are target-specific
834 f6a7d92a Aurelien Jarno
#  endif
835 f6a7d92a Aurelien Jarno
#else
836 f6a7d92a Aurelien Jarno
        a.low |= LIT64( 0xC000000000000000 );
837 f6a7d92a Aurelien Jarno
        return a;
838 f6a7d92a Aurelien Jarno
#endif
839 f6a7d92a Aurelien Jarno
    }
840 f6a7d92a Aurelien Jarno
    return a;
841 f6a7d92a Aurelien Jarno
}
842 f6a7d92a Aurelien Jarno
843 f6a7d92a Aurelien Jarno
/*----------------------------------------------------------------------------
844 158142c2 bellard
| Returns the result of converting the extended double-precision floating-
845 158142c2 bellard
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
846 158142c2 bellard
| invalid exception is raised.
847 158142c2 bellard
*----------------------------------------------------------------------------*/
848 158142c2 bellard
849 158142c2 bellard
static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
850 158142c2 bellard
{
851 158142c2 bellard
    commonNaNT z;
852 158142c2 bellard
853 158142c2 bellard
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
854 e2f42204 Aurelien Jarno
    if ( a.low >> 63 ) {
855 e2f42204 Aurelien Jarno
        z.sign = a.high >> 15;
856 e2f42204 Aurelien Jarno
        z.low = 0;
857 e2f42204 Aurelien Jarno
        z.high = a.low << 1;
858 e2f42204 Aurelien Jarno
    } else {
859 e2f42204 Aurelien Jarno
        z.sign = floatx80_default_nan_high >> 15;
860 e2f42204 Aurelien Jarno
        z.low = 0;
861 e2f42204 Aurelien Jarno
        z.high = floatx80_default_nan_low << 1;
862 e2f42204 Aurelien Jarno
    }
863 158142c2 bellard
    return z;
864 158142c2 bellard
}
865 158142c2 bellard
866 158142c2 bellard
/*----------------------------------------------------------------------------
867 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the extended
868 158142c2 bellard
| double-precision floating-point format.
869 158142c2 bellard
*----------------------------------------------------------------------------*/
870 158142c2 bellard
871 bcd4d9af Christophe Lyon
static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
872 158142c2 bellard
{
873 158142c2 bellard
    floatx80 z;
874 158142c2 bellard
875 bcd4d9af Christophe Lyon
    if ( STATUS(default_nan_mode) ) {
876 bcd4d9af Christophe Lyon
        z.low = floatx80_default_nan_low;
877 bcd4d9af Christophe Lyon
        z.high = floatx80_default_nan_high;
878 bcd4d9af Christophe Lyon
        return z;
879 bcd4d9af Christophe Lyon
    }
880 bcd4d9af Christophe Lyon
881 e2f42204 Aurelien Jarno
    if (a.high >> 1) {
882 e2f42204 Aurelien Jarno
        z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
883 e2f42204 Aurelien Jarno
        z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
884 e2f42204 Aurelien Jarno
    } else {
885 85016c98 ths
        z.low = floatx80_default_nan_low;
886 e2f42204 Aurelien Jarno
        z.high = floatx80_default_nan_high;
887 e2f42204 Aurelien Jarno
    }
888 e2f42204 Aurelien Jarno
889 158142c2 bellard
    return z;
890 158142c2 bellard
}
891 158142c2 bellard
892 158142c2 bellard
/*----------------------------------------------------------------------------
893 158142c2 bellard
| Takes two extended double-precision floating-point values `a' and `b', one
894 158142c2 bellard
| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
895 158142c2 bellard
| `b' is a signaling NaN, the invalid exception is raised.
896 158142c2 bellard
*----------------------------------------------------------------------------*/
897 158142c2 bellard
898 158142c2 bellard
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
899 158142c2 bellard
{
900 d735d695 Aurelien Jarno
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
901 d735d695 Aurelien Jarno
    flag aIsLargerSignificand;
902 158142c2 bellard
903 d735d695 Aurelien Jarno
    aIsQuietNaN = floatx80_is_quiet_nan( a );
904 158142c2 bellard
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
905 d735d695 Aurelien Jarno
    bIsQuietNaN = floatx80_is_quiet_nan( b );
906 158142c2 bellard
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
907 1f398e08 Aurelien Jarno
908 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
909 354f211b Peter Maydell
910 10201602 Aurelien Jarno
    if ( STATUS(default_nan_mode) ) {
911 10201602 Aurelien Jarno
        a.low = floatx80_default_nan_low;
912 10201602 Aurelien Jarno
        a.high = floatx80_default_nan_high;
913 10201602 Aurelien Jarno
        return a;
914 10201602 Aurelien Jarno
    }
915 10201602 Aurelien Jarno
916 354f211b Peter Maydell
    if (a.low < b.low) {
917 354f211b Peter Maydell
        aIsLargerSignificand = 0;
918 354f211b Peter Maydell
    } else if (b.low < a.low) {
919 354f211b Peter Maydell
        aIsLargerSignificand = 1;
920 354f211b Peter Maydell
    } else {
921 354f211b Peter Maydell
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
922 158142c2 bellard
    }
923 354f211b Peter Maydell
924 d735d695 Aurelien Jarno
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
925 354f211b Peter Maydell
                aIsLargerSignificand)) {
926 1f398e08 Aurelien Jarno
        return floatx80_maybe_silence_nan(b);
927 354f211b Peter Maydell
    } else {
928 1f398e08 Aurelien Jarno
        return floatx80_maybe_silence_nan(a);
929 158142c2 bellard
    }
930 158142c2 bellard
}
931 158142c2 bellard
932 158142c2 bellard
/*----------------------------------------------------------------------------
933 5a6932d5 ths
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
934 5a6932d5 ths
| NaN; otherwise returns 0.
935 158142c2 bellard
*----------------------------------------------------------------------------*/
936 158142c2 bellard
937 18569871 Peter Maydell
int float128_is_quiet_nan( float128 a )
938 158142c2 bellard
{
939 5a6932d5 ths
#if SNAN_BIT_IS_ONE
940 5a6932d5 ths
    return
941 5a6932d5 ths
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
942 5a6932d5 ths
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
943 5a6932d5 ths
#else
944 158142c2 bellard
    return
945 bb98fe42 Andreas Färber
           ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
946 158142c2 bellard
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
947 5a6932d5 ths
#endif
948 158142c2 bellard
}
949 158142c2 bellard
950 158142c2 bellard
/*----------------------------------------------------------------------------
951 158142c2 bellard
| Returns 1 if the quadruple-precision floating-point value `a' is a
952 158142c2 bellard
| signaling NaN; otherwise returns 0.
953 158142c2 bellard
*----------------------------------------------------------------------------*/
954 158142c2 bellard
955 750afe93 bellard
int float128_is_signaling_nan( float128 a )
956 158142c2 bellard
{
957 5a6932d5 ths
#if SNAN_BIT_IS_ONE
958 5a6932d5 ths
    return
959 bb98fe42 Andreas Färber
           ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
960 5a6932d5 ths
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
961 5a6932d5 ths
#else
962 158142c2 bellard
    return
963 158142c2 bellard
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
964 158142c2 bellard
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
965 5a6932d5 ths
#endif
966 158142c2 bellard
}
967 158142c2 bellard
968 158142c2 bellard
/*----------------------------------------------------------------------------
969 f6a7d92a Aurelien Jarno
| Returns a quiet NaN if the quadruple-precision floating point value `a' is
970 f6a7d92a Aurelien Jarno
| a signaling NaN; otherwise returns `a'.
971 f6a7d92a Aurelien Jarno
*----------------------------------------------------------------------------*/
972 f6a7d92a Aurelien Jarno
973 f6a7d92a Aurelien Jarno
float128 float128_maybe_silence_nan( float128 a )
974 f6a7d92a Aurelien Jarno
{
975 f6a7d92a Aurelien Jarno
    if (float128_is_signaling_nan(a)) {
976 f6a7d92a Aurelien Jarno
#if SNAN_BIT_IS_ONE
977 d2fbca94 Guan Xuetao
#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
978 f6a7d92a Aurelien Jarno
        a.low = float128_default_nan_low;
979 f6a7d92a Aurelien Jarno
        a.high = float128_default_nan_high;
980 f6a7d92a Aurelien Jarno
#  else
981 f6a7d92a Aurelien Jarno
#    error Rules for silencing a signaling NaN are target-specific
982 f6a7d92a Aurelien Jarno
#  endif
983 f6a7d92a Aurelien Jarno
#else
984 f6a7d92a Aurelien Jarno
        a.high |= LIT64( 0x0000800000000000 );
985 f6a7d92a Aurelien Jarno
        return a;
986 f6a7d92a Aurelien Jarno
#endif
987 f6a7d92a Aurelien Jarno
    }
988 f6a7d92a Aurelien Jarno
    return a;
989 f6a7d92a Aurelien Jarno
}
990 f6a7d92a Aurelien Jarno
991 f6a7d92a Aurelien Jarno
/*----------------------------------------------------------------------------
992 158142c2 bellard
| Returns the result of converting the quadruple-precision floating-point NaN
993 158142c2 bellard
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
994 158142c2 bellard
| exception is raised.
995 158142c2 bellard
*----------------------------------------------------------------------------*/
996 158142c2 bellard
997 158142c2 bellard
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
998 158142c2 bellard
{
999 158142c2 bellard
    commonNaNT z;
1000 158142c2 bellard
1001 158142c2 bellard
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
1002 158142c2 bellard
    z.sign = a.high>>63;
1003 158142c2 bellard
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
1004 158142c2 bellard
    return z;
1005 158142c2 bellard
}
1006 158142c2 bellard
1007 158142c2 bellard
/*----------------------------------------------------------------------------
1008 158142c2 bellard
| Returns the result of converting the canonical NaN `a' to the quadruple-
1009 158142c2 bellard
| precision floating-point format.
1010 158142c2 bellard
*----------------------------------------------------------------------------*/
1011 158142c2 bellard
1012 bcd4d9af Christophe Lyon
static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
1013 158142c2 bellard
{
1014 158142c2 bellard
    float128 z;
1015 158142c2 bellard
1016 bcd4d9af Christophe Lyon
    if ( STATUS(default_nan_mode) ) {
1017 bcd4d9af Christophe Lyon
        z.low = float128_default_nan_low;
1018 bcd4d9af Christophe Lyon
        z.high = float128_default_nan_high;
1019 bcd4d9af Christophe Lyon
        return z;
1020 bcd4d9af Christophe Lyon
    }
1021 bcd4d9af Christophe Lyon
1022 158142c2 bellard
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
1023 bb98fe42 Andreas Färber
    z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
1024 158142c2 bellard
    return z;
1025 158142c2 bellard
}
1026 158142c2 bellard
1027 158142c2 bellard
/*----------------------------------------------------------------------------
1028 158142c2 bellard
| Takes two quadruple-precision floating-point values `a' and `b', one of
1029 158142c2 bellard
| which is a NaN, and returns the appropriate NaN result.  If either `a' or
1030 158142c2 bellard
| `b' is a signaling NaN, the invalid exception is raised.
1031 158142c2 bellard
*----------------------------------------------------------------------------*/
1032 158142c2 bellard
1033 158142c2 bellard
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
1034 158142c2 bellard
{
1035 d735d695 Aurelien Jarno
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
1036 d735d695 Aurelien Jarno
    flag aIsLargerSignificand;
1037 158142c2 bellard
1038 d735d695 Aurelien Jarno
    aIsQuietNaN = float128_is_quiet_nan( a );
1039 158142c2 bellard
    aIsSignalingNaN = float128_is_signaling_nan( a );
1040 d735d695 Aurelien Jarno
    bIsQuietNaN = float128_is_quiet_nan( b );
1041 158142c2 bellard
    bIsSignalingNaN = float128_is_signaling_nan( b );
1042 1f398e08 Aurelien Jarno
1043 158142c2 bellard
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1044 354f211b Peter Maydell
1045 10201602 Aurelien Jarno
    if ( STATUS(default_nan_mode) ) {
1046 10201602 Aurelien Jarno
        a.low = float128_default_nan_low;
1047 10201602 Aurelien Jarno
        a.high = float128_default_nan_high;
1048 10201602 Aurelien Jarno
        return a;
1049 10201602 Aurelien Jarno
    }
1050 10201602 Aurelien Jarno
1051 354f211b Peter Maydell
    if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
1052 354f211b Peter Maydell
        aIsLargerSignificand = 0;
1053 354f211b Peter Maydell
    } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
1054 354f211b Peter Maydell
        aIsLargerSignificand = 1;
1055 354f211b Peter Maydell
    } else {
1056 354f211b Peter Maydell
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
1057 158142c2 bellard
    }
1058 354f211b Peter Maydell
1059 d735d695 Aurelien Jarno
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
1060 354f211b Peter Maydell
                aIsLargerSignificand)) {
1061 1f398e08 Aurelien Jarno
        return float128_maybe_silence_nan(b);
1062 354f211b Peter Maydell
    } else {
1063 1f398e08 Aurelien Jarno
        return float128_maybe_silence_nan(a);
1064 158142c2 bellard
    }
1065 158142c2 bellard
}