xref: /qemu/fpu/softfloat-specialize.c.inc (revision 6c301485)
1139c1837SPaolo Bonzini/*
2139c1837SPaolo Bonzini * QEMU float support
3139c1837SPaolo Bonzini *
4139c1837SPaolo Bonzini * The code in this source file is derived from release 2a of the SoftFloat
5139c1837SPaolo Bonzini * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
6139c1837SPaolo Bonzini * some later contributions) are provided under that license, as detailed below.
7139c1837SPaolo Bonzini * It has subsequently been modified by contributors to the QEMU Project,
8139c1837SPaolo Bonzini * so some portions are provided under:
9139c1837SPaolo Bonzini *  the SoftFloat-2a license
10139c1837SPaolo Bonzini *  the BSD license
11139c1837SPaolo Bonzini *  GPL-v2-or-later
12139c1837SPaolo Bonzini *
13139c1837SPaolo Bonzini * Any future contributions to this file after December 1st 2014 will be
14139c1837SPaolo Bonzini * taken to be licensed under the Softfloat-2a license unless specifically
15139c1837SPaolo Bonzini * indicated otherwise.
16139c1837SPaolo Bonzini */
17139c1837SPaolo Bonzini
18139c1837SPaolo Bonzini/*
19139c1837SPaolo Bonzini===============================================================================
20139c1837SPaolo BonziniThis C source fragment is part of the SoftFloat IEC/IEEE Floating-point
21139c1837SPaolo BonziniArithmetic Package, Release 2a.
22139c1837SPaolo Bonzini
23139c1837SPaolo BonziniWritten by John R. Hauser.  This work was made possible in part by the
24139c1837SPaolo BonziniInternational Computer Science Institute, located at Suite 600, 1947 Center
25139c1837SPaolo BonziniStreet, Berkeley, California 94704.  Funding was partially provided by the
26139c1837SPaolo BonziniNational Science Foundation under grant MIP-9311980.  The original version
27139c1837SPaolo Bonziniof this code was written as part of a project to build a fixed-point vector
28139c1837SPaolo Bonziniprocessor in collaboration with the University of California at Berkeley,
29139c1837SPaolo Bonzinioverseen by Profs. Nelson Morgan and John Wawrzynek.  More information
30139c1837SPaolo Bonziniis available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
31139c1837SPaolo Bonziniarithmetic/SoftFloat.html'.
32139c1837SPaolo Bonzini
33139c1837SPaolo BonziniTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
34139c1837SPaolo Bonzinihas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
35139c1837SPaolo BonziniTIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
36139c1837SPaolo BonziniPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
37139c1837SPaolo BonziniAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
38139c1837SPaolo Bonzini
39139c1837SPaolo BonziniDerivative works are acceptable, even for commercial purposes, so long as
40139c1837SPaolo Bonzini(1) they include prominent notice that the work is derivative, and (2) they
41139c1837SPaolo Bonziniinclude prominent notice akin to these four paragraphs for those parts of
42139c1837SPaolo Bonzinithis code that are retained.
43139c1837SPaolo Bonzini
44139c1837SPaolo Bonzini===============================================================================
45139c1837SPaolo Bonzini*/
46139c1837SPaolo Bonzini
47139c1837SPaolo Bonzini/* BSD licensing:
48139c1837SPaolo Bonzini * Copyright (c) 2006, Fabrice Bellard
49139c1837SPaolo Bonzini * All rights reserved.
50139c1837SPaolo Bonzini *
51139c1837SPaolo Bonzini * Redistribution and use in source and binary forms, with or without
52139c1837SPaolo Bonzini * modification, are permitted provided that the following conditions are met:
53139c1837SPaolo Bonzini *
54139c1837SPaolo Bonzini * 1. Redistributions of source code must retain the above copyright notice,
55139c1837SPaolo Bonzini * this list of conditions and the following disclaimer.
56139c1837SPaolo Bonzini *
57139c1837SPaolo Bonzini * 2. Redistributions in binary form must reproduce the above copyright notice,
58139c1837SPaolo Bonzini * this list of conditions and the following disclaimer in the documentation
59139c1837SPaolo Bonzini * and/or other materials provided with the distribution.
60139c1837SPaolo Bonzini *
61139c1837SPaolo Bonzini * 3. Neither the name of the copyright holder nor the names of its contributors
62139c1837SPaolo Bonzini * may be used to endorse or promote products derived from this software without
63139c1837SPaolo Bonzini * specific prior written permission.
64139c1837SPaolo Bonzini *
65139c1837SPaolo Bonzini * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
66139c1837SPaolo Bonzini * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67139c1837SPaolo Bonzini * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
68139c1837SPaolo Bonzini * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
69139c1837SPaolo Bonzini * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
70139c1837SPaolo Bonzini * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
71139c1837SPaolo Bonzini * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
72139c1837SPaolo Bonzini * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
73139c1837SPaolo Bonzini * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
74139c1837SPaolo Bonzini * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
75139c1837SPaolo Bonzini * THE POSSIBILITY OF SUCH DAMAGE.
76139c1837SPaolo Bonzini */
77139c1837SPaolo Bonzini
78139c1837SPaolo Bonzini/* Portions of this work are licensed under the terms of the GNU GPL,
79139c1837SPaolo Bonzini * version 2 or later. See the COPYING file in the top-level directory.
80139c1837SPaolo Bonzini */
81139c1837SPaolo Bonzini
82cc43c692SMax Filippov/*
83cc43c692SMax Filippov * Define whether architecture deviates from IEEE in not supporting
84139c1837SPaolo Bonzini * signaling NaNs (so all NaNs are treated as quiet).
85139c1837SPaolo Bonzini */
86cc43c692SMax Filippovstatic inline bool no_signaling_nans(float_status *status)
87cc43c692SMax Filippov{
88139c1837SPaolo Bonzini#if defined(TARGET_XTENSA)
89cc43c692SMax Filippov    return status->no_signaling_nans;
90cc43c692SMax Filippov#else
91cc43c692SMax Filippov    return false;
92139c1837SPaolo Bonzini#endif
93cc43c692SMax Filippov}
94139c1837SPaolo Bonzini
95139c1837SPaolo Bonzini/* Define how the architecture discriminates signaling NaNs.
96139c1837SPaolo Bonzini * This done with the most significant bit of the fraction.
97139c1837SPaolo Bonzini * In IEEE 754-1985 this was implementation defined, but in IEEE 754-2008
98139c1837SPaolo Bonzini * the msb must be zero.  MIPS is (so far) unique in supporting both the
99139c1837SPaolo Bonzini * 2008 revision and backward compatibility with their original choice.
100139c1837SPaolo Bonzini * Thus for MIPS we must make the choice at runtime.
101139c1837SPaolo Bonzini */
102139c1837SPaolo Bonzinistatic inline bool snan_bit_is_one(float_status *status)
103139c1837SPaolo Bonzini{
104139c1837SPaolo Bonzini#if defined(TARGET_MIPS)
105139c1837SPaolo Bonzini    return status->snan_bit_is_one;
10643692239SMarkus Armbruster#elif defined(TARGET_HPPA) || defined(TARGET_SH4)
107139c1837SPaolo Bonzini    return 1;
108139c1837SPaolo Bonzini#else
109139c1837SPaolo Bonzini    return 0;
110139c1837SPaolo Bonzini#endif
111139c1837SPaolo Bonzini}
112139c1837SPaolo Bonzini
113139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
114139c1837SPaolo Bonzini| For the deconstructed floating-point with fraction FRAC, return true
115139c1837SPaolo Bonzini| if the fraction represents a signalling NaN; otherwise false.
116139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
117139c1837SPaolo Bonzini
118139c1837SPaolo Bonzinistatic bool parts_is_snan_frac(uint64_t frac, float_status *status)
119139c1837SPaolo Bonzini{
120cc43c692SMax Filippov    if (no_signaling_nans(status)) {
121139c1837SPaolo Bonzini        return false;
122cc43c692SMax Filippov    } else {
123139c1837SPaolo Bonzini        bool msb = extract64(frac, DECOMPOSED_BINARY_POINT - 1, 1);
124139c1837SPaolo Bonzini        return msb == snan_bit_is_one(status);
125cc43c692SMax Filippov    }
126139c1837SPaolo Bonzini}
127139c1837SPaolo Bonzini
128139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
129139c1837SPaolo Bonzini| The pattern for a default generated deconstructed floating-point NaN.
130139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
131139c1837SPaolo Bonzini
1320fc07cadSRichard Hendersonstatic void parts64_default_nan(FloatParts64 *p, float_status *status)
133139c1837SPaolo Bonzini{
134139c1837SPaolo Bonzini    bool sign = 0;
135139c1837SPaolo Bonzini    uint64_t frac;
136139c1837SPaolo Bonzini
137139c1837SPaolo Bonzini#if defined(TARGET_SPARC) || defined(TARGET_M68K)
138139c1837SPaolo Bonzini    /* !snan_bit_is_one, set all bits */
139139c1837SPaolo Bonzini    frac = (1ULL << DECOMPOSED_BINARY_POINT) - 1;
140139c1837SPaolo Bonzini#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
141139c1837SPaolo Bonzini    || defined(TARGET_MICROBLAZE)
142139c1837SPaolo Bonzini    /* !snan_bit_is_one, set sign and msb */
143139c1837SPaolo Bonzini    frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
144139c1837SPaolo Bonzini    sign = 1;
145139c1837SPaolo Bonzini#elif defined(TARGET_HPPA)
146139c1837SPaolo Bonzini    /* snan_bit_is_one, set msb-1.  */
147139c1837SPaolo Bonzini    frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2);
148c0336c87STaylor Simpson#elif defined(TARGET_HEXAGON)
149c0336c87STaylor Simpson    sign = 1;
150c0336c87STaylor Simpson    frac = ~0ULL;
151139c1837SPaolo Bonzini#else
15243692239SMarkus Armbruster    /*
15343692239SMarkus Armbruster     * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
15443692239SMarkus Armbruster     * S390, SH4, TriCore, and Xtensa.  Our other supported targets,
155*6c301485SPhilippe Mathieu-Daudé     * such CRIS, do not have floating-point.
156139c1837SPaolo Bonzini     */
157139c1837SPaolo Bonzini    if (snan_bit_is_one(status)) {
158139c1837SPaolo Bonzini        /* set all bits other than msb */
159139c1837SPaolo Bonzini        frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1;
160139c1837SPaolo Bonzini    } else {
161139c1837SPaolo Bonzini        /* set msb */
162139c1837SPaolo Bonzini        frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
163139c1837SPaolo Bonzini    }
164139c1837SPaolo Bonzini#endif
165139c1837SPaolo Bonzini
1660fc07cadSRichard Henderson    *p = (FloatParts64) {
167139c1837SPaolo Bonzini        .cls = float_class_qnan,
168139c1837SPaolo Bonzini        .sign = sign,
169139c1837SPaolo Bonzini        .exp = INT_MAX,
170139c1837SPaolo Bonzini        .frac = frac
171139c1837SPaolo Bonzini    };
172139c1837SPaolo Bonzini}
173139c1837SPaolo Bonzini
174e9034ea8SRichard Hendersonstatic void parts128_default_nan(FloatParts128 *p, float_status *status)
175e9034ea8SRichard Henderson{
176e9034ea8SRichard Henderson    /*
177e9034ea8SRichard Henderson     * Extrapolate from the choices made by parts64_default_nan to fill
178e9034ea8SRichard Henderson     * in the quad-floating format.  If the low bit is set, assume we
179e9034ea8SRichard Henderson     * want to set all non-snan bits.
180e9034ea8SRichard Henderson     */
181e9034ea8SRichard Henderson    FloatParts64 p64;
182e9034ea8SRichard Henderson    parts64_default_nan(&p64, status);
183e9034ea8SRichard Henderson
184e9034ea8SRichard Henderson    *p = (FloatParts128) {
185e9034ea8SRichard Henderson        .cls = float_class_qnan,
186e9034ea8SRichard Henderson        .sign = p64.sign,
187e9034ea8SRichard Henderson        .exp = INT_MAX,
188e9034ea8SRichard Henderson        .frac_hi = p64.frac,
189e9034ea8SRichard Henderson        .frac_lo = -(p64.frac & 1)
190e9034ea8SRichard Henderson    };
191e9034ea8SRichard Henderson}
192e9034ea8SRichard Henderson
193139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
194139c1837SPaolo Bonzini| Returns a quiet NaN from a signalling NaN for the deconstructed
195139c1837SPaolo Bonzini| floating-point parts.
196139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
197139c1837SPaolo Bonzini
19892ff426dSRichard Hendersonstatic uint64_t parts_silence_nan_frac(uint64_t frac, float_status *status)
199139c1837SPaolo Bonzini{
200cc43c692SMax Filippov    g_assert(!no_signaling_nans(status));
201a777d603SRichard Henderson
202a777d603SRichard Henderson    /* The only snan_bit_is_one target without default_nan_mode is HPPA. */
203a777d603SRichard Henderson    if (snan_bit_is_one(status)) {
20492ff426dSRichard Henderson        frac &= ~(1ULL << (DECOMPOSED_BINARY_POINT - 1));
20592ff426dSRichard Henderson        frac |= 1ULL << (DECOMPOSED_BINARY_POINT - 2);
206139c1837SPaolo Bonzini    } else {
20792ff426dSRichard Henderson        frac |= 1ULL << (DECOMPOSED_BINARY_POINT - 1);
208139c1837SPaolo Bonzini    }
20992ff426dSRichard Henderson    return frac;
21092ff426dSRichard Henderson}
21192ff426dSRichard Henderson
21292ff426dSRichard Hendersonstatic void parts64_silence_nan(FloatParts64 *p, float_status *status)
21392ff426dSRichard Henderson{
21492ff426dSRichard Henderson    p->frac = parts_silence_nan_frac(p->frac, status);
21592ff426dSRichard Henderson    p->cls = float_class_qnan;
216139c1837SPaolo Bonzini}
217139c1837SPaolo Bonzini
2180018b1f4SRichard Hendersonstatic void parts128_silence_nan(FloatParts128 *p, float_status *status)
2190018b1f4SRichard Henderson{
2200018b1f4SRichard Henderson    p->frac_hi = parts_silence_nan_frac(p->frac_hi, status);
2210018b1f4SRichard Henderson    p->cls = float_class_qnan;
2220018b1f4SRichard Henderson}
2230018b1f4SRichard Henderson
224139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
225139c1837SPaolo Bonzini| The pattern for a default generated extended double-precision NaN.
226139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
227139c1837SPaolo Bonzinifloatx80 floatx80_default_nan(float_status *status)
228139c1837SPaolo Bonzini{
229139c1837SPaolo Bonzini    floatx80 r;
230139c1837SPaolo Bonzini
231139c1837SPaolo Bonzini    /* None of the targets that have snan_bit_is_one use floatx80.  */
232139c1837SPaolo Bonzini    assert(!snan_bit_is_one(status));
233139c1837SPaolo Bonzini#if defined(TARGET_M68K)
234139c1837SPaolo Bonzini    r.low = UINT64_C(0xFFFFFFFFFFFFFFFF);
235139c1837SPaolo Bonzini    r.high = 0x7FFF;
236139c1837SPaolo Bonzini#else
237139c1837SPaolo Bonzini    /* X86 */
238139c1837SPaolo Bonzini    r.low = UINT64_C(0xC000000000000000);
239139c1837SPaolo Bonzini    r.high = 0xFFFF;
240139c1837SPaolo Bonzini#endif
241139c1837SPaolo Bonzini    return r;
242139c1837SPaolo Bonzini}
243139c1837SPaolo Bonzini
244139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
245139c1837SPaolo Bonzini| The pattern for a default generated extended double-precision inf.
246139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
247139c1837SPaolo Bonzini
248139c1837SPaolo Bonzini#define floatx80_infinity_high 0x7FFF
249139c1837SPaolo Bonzini#if defined(TARGET_M68K)
250139c1837SPaolo Bonzini#define floatx80_infinity_low  UINT64_C(0x0000000000000000)
251139c1837SPaolo Bonzini#else
252139c1837SPaolo Bonzini#define floatx80_infinity_low  UINT64_C(0x8000000000000000)
253139c1837SPaolo Bonzini#endif
254139c1837SPaolo Bonzini
255139c1837SPaolo Bonziniconst floatx80 floatx80_infinity
256139c1837SPaolo Bonzini    = make_floatx80_init(floatx80_infinity_high, floatx80_infinity_low);
257139c1837SPaolo Bonzini
258139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
259139c1837SPaolo Bonzini| Returns 1 if the half-precision floating-point value `a' is a quiet
260139c1837SPaolo Bonzini| NaN; otherwise returns 0.
261139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
262139c1837SPaolo Bonzini
263139c1837SPaolo Bonzinibool float16_is_quiet_nan(float16 a_, float_status *status)
264139c1837SPaolo Bonzini{
265cc43c692SMax Filippov    if (no_signaling_nans(status)) {
266139c1837SPaolo Bonzini        return float16_is_any_nan(a_);
267cc43c692SMax Filippov    } else {
268139c1837SPaolo Bonzini        uint16_t a = float16_val(a_);
269139c1837SPaolo Bonzini        if (snan_bit_is_one(status)) {
270139c1837SPaolo Bonzini            return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
271139c1837SPaolo Bonzini        } else {
272cc43c692SMax Filippov
273139c1837SPaolo Bonzini            return ((a >> 9) & 0x3F) == 0x3F;
274139c1837SPaolo Bonzini        }
275cc43c692SMax Filippov    }
276139c1837SPaolo Bonzini}
277139c1837SPaolo Bonzini
278139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
2795ebf5f4bSLIU Zhiwei| Returns 1 if the bfloat16 value `a' is a quiet
2805ebf5f4bSLIU Zhiwei| NaN; otherwise returns 0.
2815ebf5f4bSLIU Zhiwei*----------------------------------------------------------------------------*/
2825ebf5f4bSLIU Zhiwei
2835ebf5f4bSLIU Zhiweibool bfloat16_is_quiet_nan(bfloat16 a_, float_status *status)
2845ebf5f4bSLIU Zhiwei{
2855ebf5f4bSLIU Zhiwei    if (no_signaling_nans(status)) {
2865ebf5f4bSLIU Zhiwei        return bfloat16_is_any_nan(a_);
2875ebf5f4bSLIU Zhiwei    } else {
2885ebf5f4bSLIU Zhiwei        uint16_t a = a_;
2895ebf5f4bSLIU Zhiwei        if (snan_bit_is_one(status)) {
2905ebf5f4bSLIU Zhiwei            return (((a >> 6) & 0x1FF) == 0x1FE) && (a & 0x3F);
2915ebf5f4bSLIU Zhiwei        } else {
2925ebf5f4bSLIU Zhiwei            return ((a >> 6) & 0x1FF) == 0x1FF;
2935ebf5f4bSLIU Zhiwei        }
2945ebf5f4bSLIU Zhiwei    }
2955ebf5f4bSLIU Zhiwei}
2965ebf5f4bSLIU Zhiwei
2975ebf5f4bSLIU Zhiwei/*----------------------------------------------------------------------------
298139c1837SPaolo Bonzini| Returns 1 if the half-precision floating-point value `a' is a signaling
299139c1837SPaolo Bonzini| NaN; otherwise returns 0.
300139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
301139c1837SPaolo Bonzini
302139c1837SPaolo Bonzinibool float16_is_signaling_nan(float16 a_, float_status *status)
303139c1837SPaolo Bonzini{
304cc43c692SMax Filippov    if (no_signaling_nans(status)) {
305139c1837SPaolo Bonzini        return 0;
306cc43c692SMax Filippov    } else {
307139c1837SPaolo Bonzini        uint16_t a = float16_val(a_);
308139c1837SPaolo Bonzini        if (snan_bit_is_one(status)) {
309139c1837SPaolo Bonzini            return ((a >> 9) & 0x3F) == 0x3F;
310139c1837SPaolo Bonzini        } else {
311139c1837SPaolo Bonzini            return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
312139c1837SPaolo Bonzini        }
313cc43c692SMax Filippov    }
314139c1837SPaolo Bonzini}
315139c1837SPaolo Bonzini
316139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
3175ebf5f4bSLIU Zhiwei| Returns 1 if the bfloat16 value `a' is a signaling
3185ebf5f4bSLIU Zhiwei| NaN; otherwise returns 0.
3195ebf5f4bSLIU Zhiwei*----------------------------------------------------------------------------*/
3205ebf5f4bSLIU Zhiwei
3215ebf5f4bSLIU Zhiweibool bfloat16_is_signaling_nan(bfloat16 a_, float_status *status)
3225ebf5f4bSLIU Zhiwei{
3235ebf5f4bSLIU Zhiwei    if (no_signaling_nans(status)) {
3245ebf5f4bSLIU Zhiwei        return 0;
3255ebf5f4bSLIU Zhiwei    } else {
3265ebf5f4bSLIU Zhiwei        uint16_t a = a_;
3275ebf5f4bSLIU Zhiwei        if (snan_bit_is_one(status)) {
3285ebf5f4bSLIU Zhiwei            return ((a >> 6) & 0x1FF) == 0x1FF;
3295ebf5f4bSLIU Zhiwei        } else {
3305ebf5f4bSLIU Zhiwei            return (((a >> 6) & 0x1FF) == 0x1FE) && (a & 0x3F);
3315ebf5f4bSLIU Zhiwei        }
3325ebf5f4bSLIU Zhiwei    }
3335ebf5f4bSLIU Zhiwei}
3345ebf5f4bSLIU Zhiwei
3355ebf5f4bSLIU Zhiwei/*----------------------------------------------------------------------------
336139c1837SPaolo Bonzini| Returns 1 if the single-precision floating-point value `a' is a quiet
337139c1837SPaolo Bonzini| NaN; otherwise returns 0.
338139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
339139c1837SPaolo Bonzini
340139c1837SPaolo Bonzinibool float32_is_quiet_nan(float32 a_, float_status *status)
341139c1837SPaolo Bonzini{
342cc43c692SMax Filippov    if (no_signaling_nans(status)) {
343139c1837SPaolo Bonzini        return float32_is_any_nan(a_);
344cc43c692SMax Filippov    } else {
345139c1837SPaolo Bonzini        uint32_t a = float32_val(a_);
346139c1837SPaolo Bonzini        if (snan_bit_is_one(status)) {
347139c1837SPaolo Bonzini            return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
348139c1837SPaolo Bonzini        } else {
349139c1837SPaolo Bonzini            return ((uint32_t)(a << 1) >= 0xFF800000);
350139c1837SPaolo Bonzini        }
351cc43c692SMax Filippov    }
352139c1837SPaolo Bonzini}
353139c1837SPaolo Bonzini
354139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
355139c1837SPaolo Bonzini| Returns 1 if the single-precision floating-point value `a' is a signaling
356139c1837SPaolo Bonzini| NaN; otherwise returns 0.
357139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
358139c1837SPaolo Bonzini
359139c1837SPaolo Bonzinibool float32_is_signaling_nan(float32 a_, float_status *status)
360139c1837SPaolo Bonzini{
361cc43c692SMax Filippov    if (no_signaling_nans(status)) {
362139c1837SPaolo Bonzini        return 0;
363cc43c692SMax Filippov    } else {
364139c1837SPaolo Bonzini        uint32_t a = float32_val(a_);
365139c1837SPaolo Bonzini        if (snan_bit_is_one(status)) {
366139c1837SPaolo Bonzini            return ((uint32_t)(a << 1) >= 0xFF800000);
367139c1837SPaolo Bonzini        } else {
368139c1837SPaolo Bonzini            return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
369139c1837SPaolo Bonzini        }
370cc43c692SMax Filippov    }
371139c1837SPaolo Bonzini}
372139c1837SPaolo Bonzini
373139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
374139c1837SPaolo Bonzini| Select which NaN to propagate for a two-input operation.
375139c1837SPaolo Bonzini| IEEE754 doesn't specify all the details of this, so the
376139c1837SPaolo Bonzini| algorithm is target-specific.
377139c1837SPaolo Bonzini| The routine is passed various bits of information about the
378139c1837SPaolo Bonzini| two NaNs and should return 0 to select NaN a and 1 for NaN b.
379139c1837SPaolo Bonzini| Note that signalling NaNs are always squashed to quiet NaNs
380139c1837SPaolo Bonzini| by the caller, by calling floatXX_silence_nan() before
381139c1837SPaolo Bonzini| returning them.
382139c1837SPaolo Bonzini|
383139c1837SPaolo Bonzini| aIsLargerSignificand is only valid if both a and b are NaNs
384139c1837SPaolo Bonzini| of some kind, and is true if a has the larger significand,
385139c1837SPaolo Bonzini| or if both a and b have the same significand but a is
386139c1837SPaolo Bonzini| positive but b is negative. It is only needed for the x87
387139c1837SPaolo Bonzini| tie-break rule.
388139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
389139c1837SPaolo Bonzini
390139c1837SPaolo Bonzinistatic int pickNaN(FloatClass a_cls, FloatClass b_cls,
391913602e3SMax Filippov                   bool aIsLargerSignificand, float_status *status)
392139c1837SPaolo Bonzini{
39363dd7bcbSIlya Leoshkevich#if defined(TARGET_ARM) || defined(TARGET_MIPS) || defined(TARGET_HPPA) || \
394f45fd24cSPeter Maydell    defined(TARGET_LOONGARCH64) || defined(TARGET_S390X)
395139c1837SPaolo Bonzini    /* ARM mandated NaN propagation rules (see FPProcessNaNs()), take
396139c1837SPaolo Bonzini     * the first of:
397139c1837SPaolo Bonzini     *  1. A if it is signaling
398139c1837SPaolo Bonzini     *  2. B if it is signaling
399139c1837SPaolo Bonzini     *  3. A (quiet)
400139c1837SPaolo Bonzini     *  4. B (quiet)
401139c1837SPaolo Bonzini     * A signaling NaN is always quietened before returning it.
402139c1837SPaolo Bonzini     */
403139c1837SPaolo Bonzini    /* According to MIPS specifications, if one of the two operands is
404139c1837SPaolo Bonzini     * a sNaN, a new qNaN has to be generated. This is done in
405139c1837SPaolo Bonzini     * floatXX_silence_nan(). For qNaN inputs the specifications
406139c1837SPaolo Bonzini     * says: "When possible, this QNaN result is one of the operand QNaN
407139c1837SPaolo Bonzini     * values." In practice it seems that most implementations choose
408139c1837SPaolo Bonzini     * the first operand if both operands are qNaN. In short this gives
409139c1837SPaolo Bonzini     * the following rules:
410139c1837SPaolo Bonzini     *  1. A if it is signaling
411139c1837SPaolo Bonzini     *  2. B if it is signaling
412139c1837SPaolo Bonzini     *  3. A (quiet)
413139c1837SPaolo Bonzini     *  4. B (quiet)
414139c1837SPaolo Bonzini     * A signaling NaN is always silenced before returning it.
415139c1837SPaolo Bonzini     */
416139c1837SPaolo Bonzini    if (is_snan(a_cls)) {
417139c1837SPaolo Bonzini        return 0;
418139c1837SPaolo Bonzini    } else if (is_snan(b_cls)) {
419139c1837SPaolo Bonzini        return 1;
420139c1837SPaolo Bonzini    } else if (is_qnan(a_cls)) {
421139c1837SPaolo Bonzini        return 0;
422139c1837SPaolo Bonzini    } else {
423139c1837SPaolo Bonzini        return 1;
424139c1837SPaolo Bonzini    }
425913602e3SMax Filippov#elif defined(TARGET_PPC) || defined(TARGET_M68K)
426139c1837SPaolo Bonzini    /* PowerPC propagation rules:
427139c1837SPaolo Bonzini     *  1. A if it sNaN or qNaN
428139c1837SPaolo Bonzini     *  2. B if it sNaN or qNaN
429139c1837SPaolo Bonzini     * A signaling NaN is always silenced before returning it.
430139c1837SPaolo Bonzini     */
431139c1837SPaolo Bonzini    /* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
432139c1837SPaolo Bonzini     * 3.4 FLOATING-POINT INSTRUCTION DETAILS
433139c1837SPaolo Bonzini     * If either operand, but not both operands, of an operation is a
434139c1837SPaolo Bonzini     * nonsignaling NaN, then that NaN is returned as the result. If both
435139c1837SPaolo Bonzini     * operands are nonsignaling NaNs, then the destination operand
436139c1837SPaolo Bonzini     * nonsignaling NaN is returned as the result.
437139c1837SPaolo Bonzini     * If either operand to an operation is a signaling NaN (SNaN), then the
438139c1837SPaolo Bonzini     * SNaN bit is set in the FPSR EXC byte. If the SNaN exception enable bit
439139c1837SPaolo Bonzini     * is set in the FPCR ENABLE byte, then the exception is taken and the
440139c1837SPaolo Bonzini     * destination is not modified. If the SNaN exception enable bit is not
441139c1837SPaolo Bonzini     * set, setting the SNaN bit in the operand to a one converts the SNaN to
442139c1837SPaolo Bonzini     * a nonsignaling NaN. The operation then continues as described in the
443139c1837SPaolo Bonzini     * preceding paragraph for nonsignaling NaNs.
444139c1837SPaolo Bonzini     */
445139c1837SPaolo Bonzini    if (is_nan(a_cls)) {
446139c1837SPaolo Bonzini        return 0;
447139c1837SPaolo Bonzini    } else {
448139c1837SPaolo Bonzini        return 1;
449139c1837SPaolo Bonzini    }
450913602e3SMax Filippov#elif defined(TARGET_XTENSA)
451913602e3SMax Filippov    /*
452913602e3SMax Filippov     * Xtensa has two NaN propagation modes.
453913602e3SMax Filippov     * Which one is active is controlled by float_status::use_first_nan.
454913602e3SMax Filippov     */
455913602e3SMax Filippov    if (status->use_first_nan) {
456913602e3SMax Filippov        if (is_nan(a_cls)) {
457913602e3SMax Filippov            return 0;
458913602e3SMax Filippov        } else {
459913602e3SMax Filippov            return 1;
460913602e3SMax Filippov        }
461913602e3SMax Filippov    } else {
462913602e3SMax Filippov        if (is_nan(b_cls)) {
463913602e3SMax Filippov            return 1;
464913602e3SMax Filippov        } else {
465913602e3SMax Filippov            return 0;
466913602e3SMax Filippov        }
467913602e3SMax Filippov    }
468139c1837SPaolo Bonzini#else
469139c1837SPaolo Bonzini    /* This implements x87 NaN propagation rules:
470139c1837SPaolo Bonzini     * SNaN + QNaN => return the QNaN
471139c1837SPaolo Bonzini     * two SNaNs => return the one with the larger significand, silenced
472139c1837SPaolo Bonzini     * two QNaNs => return the one with the larger significand
473139c1837SPaolo Bonzini     * SNaN and a non-NaN => return the SNaN, silenced
474139c1837SPaolo Bonzini     * QNaN and a non-NaN => return the QNaN
475139c1837SPaolo Bonzini     *
476139c1837SPaolo Bonzini     * If we get down to comparing significands and they are the same,
477139c1837SPaolo Bonzini     * return the NaN with the positive sign bit (if any).
478139c1837SPaolo Bonzini     */
479139c1837SPaolo Bonzini    if (is_snan(a_cls)) {
480139c1837SPaolo Bonzini        if (is_snan(b_cls)) {
481139c1837SPaolo Bonzini            return aIsLargerSignificand ? 0 : 1;
482139c1837SPaolo Bonzini        }
483139c1837SPaolo Bonzini        return is_qnan(b_cls) ? 1 : 0;
484139c1837SPaolo Bonzini    } else if (is_qnan(a_cls)) {
485139c1837SPaolo Bonzini        if (is_snan(b_cls) || !is_qnan(b_cls)) {
486139c1837SPaolo Bonzini            return 0;
487139c1837SPaolo Bonzini        } else {
488139c1837SPaolo Bonzini            return aIsLargerSignificand ? 0 : 1;
489139c1837SPaolo Bonzini        }
490139c1837SPaolo Bonzini    } else {
491139c1837SPaolo Bonzini        return 1;
492139c1837SPaolo Bonzini    }
493139c1837SPaolo Bonzini#endif
494139c1837SPaolo Bonzini}
495139c1837SPaolo Bonzini
496139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
497139c1837SPaolo Bonzini| Select which NaN to propagate for a three-input operation.
498139c1837SPaolo Bonzini| For the moment we assume that no CPU needs the 'larger significand'
499139c1837SPaolo Bonzini| information.
500139c1837SPaolo Bonzini| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
501139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
502139c1837SPaolo Bonzinistatic int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
503139c1837SPaolo Bonzini                         bool infzero, float_status *status)
504139c1837SPaolo Bonzini{
505139c1837SPaolo Bonzini#if defined(TARGET_ARM)
506139c1837SPaolo Bonzini    /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
507139c1837SPaolo Bonzini     * the default NaN
508139c1837SPaolo Bonzini     */
509139c1837SPaolo Bonzini    if (infzero && is_qnan(c_cls)) {
510bead3c9bSRichard Henderson        float_raise(float_flag_invalid | float_flag_invalid_imz, status);
511139c1837SPaolo Bonzini        return 3;
512139c1837SPaolo Bonzini    }
513139c1837SPaolo Bonzini
514139c1837SPaolo Bonzini    /* This looks different from the ARM ARM pseudocode, because the ARM ARM
515139c1837SPaolo Bonzini     * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
516139c1837SPaolo Bonzini     */
517139c1837SPaolo Bonzini    if (is_snan(c_cls)) {
518139c1837SPaolo Bonzini        return 2;
519139c1837SPaolo Bonzini    } else if (is_snan(a_cls)) {
520139c1837SPaolo Bonzini        return 0;
521139c1837SPaolo Bonzini    } else if (is_snan(b_cls)) {
522139c1837SPaolo Bonzini        return 1;
523139c1837SPaolo Bonzini    } else if (is_qnan(c_cls)) {
524139c1837SPaolo Bonzini        return 2;
525139c1837SPaolo Bonzini    } else if (is_qnan(a_cls)) {
526139c1837SPaolo Bonzini        return 0;
527139c1837SPaolo Bonzini    } else {
528139c1837SPaolo Bonzini        return 1;
529139c1837SPaolo Bonzini    }
530139c1837SPaolo Bonzini#elif defined(TARGET_MIPS)
531139c1837SPaolo Bonzini    if (snan_bit_is_one(status)) {
532139c1837SPaolo Bonzini        /*
533139c1837SPaolo Bonzini         * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
534139c1837SPaolo Bonzini         * case sets InvalidOp and returns the default NaN
535139c1837SPaolo Bonzini         */
536139c1837SPaolo Bonzini        if (infzero) {
537bead3c9bSRichard Henderson            float_raise(float_flag_invalid | float_flag_invalid_imz, status);
538139c1837SPaolo Bonzini            return 3;
539139c1837SPaolo Bonzini        }
540139c1837SPaolo Bonzini        /* Prefer sNaN over qNaN, in the a, b, c order. */
541139c1837SPaolo Bonzini        if (is_snan(a_cls)) {
542139c1837SPaolo Bonzini            return 0;
543139c1837SPaolo Bonzini        } else if (is_snan(b_cls)) {
544139c1837SPaolo Bonzini            return 1;
545139c1837SPaolo Bonzini        } else if (is_snan(c_cls)) {
546139c1837SPaolo Bonzini            return 2;
547139c1837SPaolo Bonzini        } else if (is_qnan(a_cls)) {
548139c1837SPaolo Bonzini            return 0;
549139c1837SPaolo Bonzini        } else if (is_qnan(b_cls)) {
550139c1837SPaolo Bonzini            return 1;
551139c1837SPaolo Bonzini        } else {
552139c1837SPaolo Bonzini            return 2;
553139c1837SPaolo Bonzini        }
554139c1837SPaolo Bonzini    } else {
555139c1837SPaolo Bonzini        /*
556139c1837SPaolo Bonzini         * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
557139c1837SPaolo Bonzini         * case sets InvalidOp and returns the input value 'c'
558139c1837SPaolo Bonzini         */
559139c1837SPaolo Bonzini        if (infzero) {
560bead3c9bSRichard Henderson            float_raise(float_flag_invalid | float_flag_invalid_imz, status);
561139c1837SPaolo Bonzini            return 2;
562139c1837SPaolo Bonzini        }
563139c1837SPaolo Bonzini        /* Prefer sNaN over qNaN, in the c, a, b order. */
564139c1837SPaolo Bonzini        if (is_snan(c_cls)) {
565139c1837SPaolo Bonzini            return 2;
566139c1837SPaolo Bonzini        } else if (is_snan(a_cls)) {
567139c1837SPaolo Bonzini            return 0;
568139c1837SPaolo Bonzini        } else if (is_snan(b_cls)) {
569139c1837SPaolo Bonzini            return 1;
570139c1837SPaolo Bonzini        } else if (is_qnan(c_cls)) {
571139c1837SPaolo Bonzini            return 2;
572139c1837SPaolo Bonzini        } else if (is_qnan(a_cls)) {
573139c1837SPaolo Bonzini            return 0;
574139c1837SPaolo Bonzini        } else {
575139c1837SPaolo Bonzini            return 1;
576139c1837SPaolo Bonzini        }
577139c1837SPaolo Bonzini    }
5782344f98eSSong Gao#elif defined(TARGET_LOONGARCH64)
5792344f98eSSong Gao    /*
5802344f98eSSong Gao     * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
5812344f98eSSong Gao     * case sets InvalidOp and returns the input value 'c'
5822344f98eSSong Gao     */
5832344f98eSSong Gao    if (infzero) {
5842344f98eSSong Gao        float_raise(float_flag_invalid | float_flag_invalid_imz, status);
5852344f98eSSong Gao        return 2;
5862344f98eSSong Gao    }
5872344f98eSSong Gao    /* Prefer sNaN over qNaN, in the c, a, b order. */
5882344f98eSSong Gao    if (is_snan(c_cls)) {
5892344f98eSSong Gao        return 2;
5902344f98eSSong Gao    } else if (is_snan(a_cls)) {
5912344f98eSSong Gao        return 0;
5922344f98eSSong Gao    } else if (is_snan(b_cls)) {
5932344f98eSSong Gao        return 1;
5942344f98eSSong Gao    } else if (is_qnan(c_cls)) {
5952344f98eSSong Gao        return 2;
5962344f98eSSong Gao    } else if (is_qnan(a_cls)) {
5972344f98eSSong Gao        return 0;
5982344f98eSSong Gao    } else {
5992344f98eSSong Gao        return 1;
6002344f98eSSong Gao    }
601139c1837SPaolo Bonzini#elif defined(TARGET_PPC)
602139c1837SPaolo Bonzini    /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
603139c1837SPaolo Bonzini     * to return an input NaN if we have one (ie c) rather than generating
604139c1837SPaolo Bonzini     * a default NaN
605139c1837SPaolo Bonzini     */
606139c1837SPaolo Bonzini    if (infzero) {
607bead3c9bSRichard Henderson        float_raise(float_flag_invalid | float_flag_invalid_imz, status);
608139c1837SPaolo Bonzini        return 2;
609139c1837SPaolo Bonzini    }
610139c1837SPaolo Bonzini
611139c1837SPaolo Bonzini    /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
612139c1837SPaolo Bonzini     * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
613139c1837SPaolo Bonzini     */
614139c1837SPaolo Bonzini    if (is_nan(a_cls)) {
615139c1837SPaolo Bonzini        return 0;
616139c1837SPaolo Bonzini    } else if (is_nan(c_cls)) {
617139c1837SPaolo Bonzini        return 2;
618139c1837SPaolo Bonzini    } else {
619139c1837SPaolo Bonzini        return 1;
620139c1837SPaolo Bonzini    }
6213a7f7757SFrank Chang#elif defined(TARGET_RISCV)
6223a7f7757SFrank Chang    /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
6233a7f7757SFrank Chang    if (infzero) {
624bead3c9bSRichard Henderson        float_raise(float_flag_invalid | float_flag_invalid_imz, status);
6253a7f7757SFrank Chang    }
6263a7f7757SFrank Chang    return 3; /* default NaN */
627fbcc38e4SMax Filippov#elif defined(TARGET_XTENSA)
628fbcc38e4SMax Filippov    /*
629fbcc38e4SMax Filippov     * For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
630fbcc38e4SMax Filippov     * an input NaN if we have one (ie c).
631fbcc38e4SMax Filippov     */
632fbcc38e4SMax Filippov    if (infzero) {
633bead3c9bSRichard Henderson        float_raise(float_flag_invalid | float_flag_invalid_imz, status);
634fbcc38e4SMax Filippov        return 2;
635fbcc38e4SMax Filippov    }
636fbcc38e4SMax Filippov    if (status->use_first_nan) {
637fbcc38e4SMax Filippov        if (is_nan(a_cls)) {
638fbcc38e4SMax Filippov            return 0;
639fbcc38e4SMax Filippov        } else if (is_nan(b_cls)) {
640fbcc38e4SMax Filippov            return 1;
641fbcc38e4SMax Filippov        } else {
642fbcc38e4SMax Filippov            return 2;
643fbcc38e4SMax Filippov        }
644fbcc38e4SMax Filippov    } else {
645fbcc38e4SMax Filippov        if (is_nan(c_cls)) {
646fbcc38e4SMax Filippov            return 2;
647fbcc38e4SMax Filippov        } else if (is_nan(b_cls)) {
648fbcc38e4SMax Filippov            return 1;
649fbcc38e4SMax Filippov        } else {
650fbcc38e4SMax Filippov            return 0;
651fbcc38e4SMax Filippov        }
652fbcc38e4SMax Filippov    }
653139c1837SPaolo Bonzini#else
654139c1837SPaolo Bonzini    /* A default implementation: prefer a to b to c.
655139c1837SPaolo Bonzini     * This is unlikely to actually match any real implementation.
656139c1837SPaolo Bonzini     */
657139c1837SPaolo Bonzini    if (is_nan(a_cls)) {
658139c1837SPaolo Bonzini        return 0;
659139c1837SPaolo Bonzini    } else if (is_nan(b_cls)) {
660139c1837SPaolo Bonzini        return 1;
661139c1837SPaolo Bonzini    } else {
662139c1837SPaolo Bonzini        return 2;
663139c1837SPaolo Bonzini    }
664139c1837SPaolo Bonzini#endif
665139c1837SPaolo Bonzini}
666139c1837SPaolo Bonzini
667139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
668139c1837SPaolo Bonzini| Returns 1 if the double-precision floating-point value `a' is a quiet
669139c1837SPaolo Bonzini| NaN; otherwise returns 0.
670139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
671139c1837SPaolo Bonzini
672139c1837SPaolo Bonzinibool float64_is_quiet_nan(float64 a_, float_status *status)
673139c1837SPaolo Bonzini{
674cc43c692SMax Filippov    if (no_signaling_nans(status)) {
675139c1837SPaolo Bonzini        return float64_is_any_nan(a_);
676cc43c692SMax Filippov    } else {
677139c1837SPaolo Bonzini        uint64_t a = float64_val(a_);
678139c1837SPaolo Bonzini        if (snan_bit_is_one(status)) {
679139c1837SPaolo Bonzini            return (((a >> 51) & 0xFFF) == 0xFFE)
680139c1837SPaolo Bonzini                && (a & 0x0007FFFFFFFFFFFFULL);
681139c1837SPaolo Bonzini        } else {
682139c1837SPaolo Bonzini            return ((a << 1) >= 0xFFF0000000000000ULL);
683139c1837SPaolo Bonzini        }
684cc43c692SMax Filippov    }
685139c1837SPaolo Bonzini}
686139c1837SPaolo Bonzini
687139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
688139c1837SPaolo Bonzini| Returns 1 if the double-precision floating-point value `a' is a signaling
689139c1837SPaolo Bonzini| NaN; otherwise returns 0.
690139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
691139c1837SPaolo Bonzini
692139c1837SPaolo Bonzinibool float64_is_signaling_nan(float64 a_, float_status *status)
693139c1837SPaolo Bonzini{
694cc43c692SMax Filippov    if (no_signaling_nans(status)) {
695139c1837SPaolo Bonzini        return 0;
696cc43c692SMax Filippov    } else {
697139c1837SPaolo Bonzini        uint64_t a = float64_val(a_);
698139c1837SPaolo Bonzini        if (snan_bit_is_one(status)) {
699139c1837SPaolo Bonzini            return ((a << 1) >= 0xFFF0000000000000ULL);
700139c1837SPaolo Bonzini        } else {
701139c1837SPaolo Bonzini            return (((a >> 51) & 0xFFF) == 0xFFE)
702139c1837SPaolo Bonzini                && (a & UINT64_C(0x0007FFFFFFFFFFFF));
703139c1837SPaolo Bonzini        }
704cc43c692SMax Filippov    }
705139c1837SPaolo Bonzini}
706139c1837SPaolo Bonzini
707139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
708139c1837SPaolo Bonzini| Returns 1 if the extended double-precision floating-point value `a' is a
709139c1837SPaolo Bonzini| quiet NaN; otherwise returns 0. This slightly differs from the same
710139c1837SPaolo Bonzini| function for other types as floatx80 has an explicit bit.
711139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
712139c1837SPaolo Bonzini
713139c1837SPaolo Bonziniint floatx80_is_quiet_nan(floatx80 a, float_status *status)
714139c1837SPaolo Bonzini{
715cc43c692SMax Filippov    if (no_signaling_nans(status)) {
716139c1837SPaolo Bonzini        return floatx80_is_any_nan(a);
717cc43c692SMax Filippov    } else {
718139c1837SPaolo Bonzini        if (snan_bit_is_one(status)) {
719139c1837SPaolo Bonzini            uint64_t aLow;
720139c1837SPaolo Bonzini
721139c1837SPaolo Bonzini            aLow = a.low & ~0x4000000000000000ULL;
722139c1837SPaolo Bonzini            return ((a.high & 0x7FFF) == 0x7FFF)
723139c1837SPaolo Bonzini                && (aLow << 1)
724139c1837SPaolo Bonzini                && (a.low == aLow);
725139c1837SPaolo Bonzini        } else {
726139c1837SPaolo Bonzini            return ((a.high & 0x7FFF) == 0x7FFF)
727139c1837SPaolo Bonzini                && (UINT64_C(0x8000000000000000) <= ((uint64_t)(a.low << 1)));
728139c1837SPaolo Bonzini        }
729cc43c692SMax Filippov    }
730139c1837SPaolo Bonzini}
731139c1837SPaolo Bonzini
732139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
733139c1837SPaolo Bonzini| Returns 1 if the extended double-precision floating-point value `a' is a
734139c1837SPaolo Bonzini| signaling NaN; otherwise returns 0. This slightly differs from the same
735139c1837SPaolo Bonzini| function for other types as floatx80 has an explicit bit.
736139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
737139c1837SPaolo Bonzini
738139c1837SPaolo Bonziniint floatx80_is_signaling_nan(floatx80 a, float_status *status)
739139c1837SPaolo Bonzini{
740cc43c692SMax Filippov    if (no_signaling_nans(status)) {
741139c1837SPaolo Bonzini        return 0;
742cc43c692SMax Filippov    } else {
743139c1837SPaolo Bonzini        if (snan_bit_is_one(status)) {
744139c1837SPaolo Bonzini            return ((a.high & 0x7FFF) == 0x7FFF)
745139c1837SPaolo Bonzini                && ((a.low << 1) >= 0x8000000000000000ULL);
746139c1837SPaolo Bonzini        } else {
747139c1837SPaolo Bonzini            uint64_t aLow;
748139c1837SPaolo Bonzini
749139c1837SPaolo Bonzini            aLow = a.low & ~UINT64_C(0x4000000000000000);
750139c1837SPaolo Bonzini            return ((a.high & 0x7FFF) == 0x7FFF)
751139c1837SPaolo Bonzini                && (uint64_t)(aLow << 1)
752139c1837SPaolo Bonzini                && (a.low == aLow);
753139c1837SPaolo Bonzini        }
754cc43c692SMax Filippov    }
755139c1837SPaolo Bonzini}
756139c1837SPaolo Bonzini
757139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
758139c1837SPaolo Bonzini| Returns a quiet NaN from a signalling NaN for the extended double-precision
759139c1837SPaolo Bonzini| floating point value `a'.
760139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
761139c1837SPaolo Bonzini
762139c1837SPaolo Bonzinifloatx80 floatx80_silence_nan(floatx80 a, float_status *status)
763139c1837SPaolo Bonzini{
764139c1837SPaolo Bonzini    /* None of the targets that have snan_bit_is_one use floatx80.  */
765139c1837SPaolo Bonzini    assert(!snan_bit_is_one(status));
766139c1837SPaolo Bonzini    a.low |= UINT64_C(0xC000000000000000);
767139c1837SPaolo Bonzini    return a;
768139c1837SPaolo Bonzini}
769139c1837SPaolo Bonzini
770139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
771139c1837SPaolo Bonzini| Takes two extended double-precision floating-point values `a' and `b', one
772139c1837SPaolo Bonzini| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
773139c1837SPaolo Bonzini| `b' is a signaling NaN, the invalid exception is raised.
774139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
775139c1837SPaolo Bonzini
776139c1837SPaolo Bonzinifloatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
777139c1837SPaolo Bonzini{
778139c1837SPaolo Bonzini    bool aIsLargerSignificand;
779139c1837SPaolo Bonzini    FloatClass a_cls, b_cls;
780139c1837SPaolo Bonzini
781139c1837SPaolo Bonzini    /* This is not complete, but is good enough for pickNaN.  */
782139c1837SPaolo Bonzini    a_cls = (!floatx80_is_any_nan(a)
783139c1837SPaolo Bonzini             ? float_class_normal
784139c1837SPaolo Bonzini             : floatx80_is_signaling_nan(a, status)
785139c1837SPaolo Bonzini             ? float_class_snan
786139c1837SPaolo Bonzini             : float_class_qnan);
787139c1837SPaolo Bonzini    b_cls = (!floatx80_is_any_nan(b)
788139c1837SPaolo Bonzini             ? float_class_normal
789139c1837SPaolo Bonzini             : floatx80_is_signaling_nan(b, status)
790139c1837SPaolo Bonzini             ? float_class_snan
791139c1837SPaolo Bonzini             : float_class_qnan);
792139c1837SPaolo Bonzini
793139c1837SPaolo Bonzini    if (is_snan(a_cls) || is_snan(b_cls)) {
794139c1837SPaolo Bonzini        float_raise(float_flag_invalid, status);
795139c1837SPaolo Bonzini    }
796139c1837SPaolo Bonzini
797139c1837SPaolo Bonzini    if (status->default_nan_mode) {
798139c1837SPaolo Bonzini        return floatx80_default_nan(status);
799139c1837SPaolo Bonzini    }
800139c1837SPaolo Bonzini
801139c1837SPaolo Bonzini    if (a.low < b.low) {
802139c1837SPaolo Bonzini        aIsLargerSignificand = 0;
803139c1837SPaolo Bonzini    } else if (b.low < a.low) {
804139c1837SPaolo Bonzini        aIsLargerSignificand = 1;
805139c1837SPaolo Bonzini    } else {
806139c1837SPaolo Bonzini        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
807139c1837SPaolo Bonzini    }
808139c1837SPaolo Bonzini
809913602e3SMax Filippov    if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
810139c1837SPaolo Bonzini        if (is_snan(b_cls)) {
811139c1837SPaolo Bonzini            return floatx80_silence_nan(b, status);
812139c1837SPaolo Bonzini        }
813139c1837SPaolo Bonzini        return b;
814139c1837SPaolo Bonzini    } else {
815139c1837SPaolo Bonzini        if (is_snan(a_cls)) {
816139c1837SPaolo Bonzini            return floatx80_silence_nan(a, status);
817139c1837SPaolo Bonzini        }
818139c1837SPaolo Bonzini        return a;
819139c1837SPaolo Bonzini    }
820139c1837SPaolo Bonzini}
821139c1837SPaolo Bonzini
822139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
823139c1837SPaolo Bonzini| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
824139c1837SPaolo Bonzini| NaN; otherwise returns 0.
825139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
826139c1837SPaolo Bonzini
827139c1837SPaolo Bonzinibool float128_is_quiet_nan(float128 a, float_status *status)
828139c1837SPaolo Bonzini{
829cc43c692SMax Filippov    if (no_signaling_nans(status)) {
830139c1837SPaolo Bonzini        return float128_is_any_nan(a);
831cc43c692SMax Filippov    } else {
832139c1837SPaolo Bonzini        if (snan_bit_is_one(status)) {
833139c1837SPaolo Bonzini            return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
834139c1837SPaolo Bonzini                && (a.low || (a.high & 0x00007FFFFFFFFFFFULL));
835139c1837SPaolo Bonzini        } else {
836139c1837SPaolo Bonzini            return ((a.high << 1) >= 0xFFFF000000000000ULL)
837139c1837SPaolo Bonzini                && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
838139c1837SPaolo Bonzini        }
839cc43c692SMax Filippov    }
840139c1837SPaolo Bonzini}
841139c1837SPaolo Bonzini
842139c1837SPaolo Bonzini/*----------------------------------------------------------------------------
843139c1837SPaolo Bonzini| Returns 1 if the quadruple-precision floating-point value `a' is a
844139c1837SPaolo Bonzini| signaling NaN; otherwise returns 0.
845139c1837SPaolo Bonzini*----------------------------------------------------------------------------*/
846139c1837SPaolo Bonzini
847139c1837SPaolo Bonzinibool float128_is_signaling_nan(float128 a, float_status *status)
848139c1837SPaolo Bonzini{
849cc43c692SMax Filippov    if (no_signaling_nans(status)) {
850139c1837SPaolo Bonzini        return 0;
851cc43c692SMax Filippov    } else {
852139c1837SPaolo Bonzini        if (snan_bit_is_one(status)) {
853139c1837SPaolo Bonzini            return ((a.high << 1) >= 0xFFFF000000000000ULL)
854139c1837SPaolo Bonzini                && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
855139c1837SPaolo Bonzini        } else {
856139c1837SPaolo Bonzini            return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
857139c1837SPaolo Bonzini                && (a.low || (a.high & UINT64_C(0x00007FFFFFFFFFFF)));
858139c1837SPaolo Bonzini        }
859cc43c692SMax Filippov    }
860139c1837SPaolo Bonzini}
861