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