xref: /qemu/include/fpu/softfloat.h (revision 00f9ef8f)
16b4c305cSPaolo Bonzini /*
26b4c305cSPaolo Bonzini  * QEMU float support
36b4c305cSPaolo Bonzini  *
416017c48SPeter Maydell  * The code in this source file is derived from release 2a of the SoftFloat
516017c48SPeter Maydell  * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
616017c48SPeter Maydell  * some later contributions) are provided under that license, as detailed below.
716017c48SPeter Maydell  * It has subsequently been modified by contributors to the QEMU Project,
816017c48SPeter Maydell  * so some portions are provided under:
916017c48SPeter Maydell  *  the SoftFloat-2a license
1016017c48SPeter Maydell  *  the BSD license
1116017c48SPeter Maydell  *  GPL-v2-or-later
1216017c48SPeter Maydell  *
1316017c48SPeter Maydell  * Any future contributions to this file after December 1st 2014 will be
1416017c48SPeter Maydell  * taken to be licensed under the Softfloat-2a license unless specifically
1516017c48SPeter Maydell  * indicated otherwise.
166b4c305cSPaolo Bonzini  */
176b4c305cSPaolo Bonzini 
18a7d1ac78SPeter Maydell /*
19a7d1ac78SPeter Maydell ===============================================================================
20a7d1ac78SPeter Maydell This C header file is part of the SoftFloat IEC/IEEE Floating-point
21a7d1ac78SPeter Maydell Arithmetic Package, Release 2a.
226b4c305cSPaolo Bonzini 
236b4c305cSPaolo Bonzini Written by John R. Hauser.  This work was made possible in part by the
246b4c305cSPaolo Bonzini International Computer Science Institute, located at Suite 600, 1947 Center
256b4c305cSPaolo Bonzini Street, Berkeley, California 94704.  Funding was partially provided by the
266b4c305cSPaolo Bonzini National Science Foundation under grant MIP-9311980.  The original version
276b4c305cSPaolo Bonzini of this code was written as part of a project to build a fixed-point vector
286b4c305cSPaolo Bonzini processor in collaboration with the University of California at Berkeley,
296b4c305cSPaolo Bonzini overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
30a7d1ac78SPeter Maydell is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
316b4c305cSPaolo Bonzini arithmetic/SoftFloat.html'.
326b4c305cSPaolo Bonzini 
33a7d1ac78SPeter Maydell THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
34a7d1ac78SPeter Maydell has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
35a7d1ac78SPeter Maydell TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
36a7d1ac78SPeter Maydell PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
37a7d1ac78SPeter Maydell AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
386b4c305cSPaolo Bonzini 
396b4c305cSPaolo Bonzini Derivative works are acceptable, even for commercial purposes, so long as
40a7d1ac78SPeter Maydell (1) they include prominent notice that the work is derivative, and (2) they
41a7d1ac78SPeter Maydell include prominent notice akin to these four paragraphs for those parts of
42a7d1ac78SPeter Maydell this code that are retained.
436b4c305cSPaolo Bonzini 
44a7d1ac78SPeter Maydell ===============================================================================
45a7d1ac78SPeter Maydell */
466b4c305cSPaolo Bonzini 
4716017c48SPeter Maydell /* BSD licensing:
4816017c48SPeter Maydell  * Copyright (c) 2006, Fabrice Bellard
4916017c48SPeter Maydell  * All rights reserved.
5016017c48SPeter Maydell  *
5116017c48SPeter Maydell  * Redistribution and use in source and binary forms, with or without
5216017c48SPeter Maydell  * modification, are permitted provided that the following conditions are met:
5316017c48SPeter Maydell  *
5416017c48SPeter Maydell  * 1. Redistributions of source code must retain the above copyright notice,
5516017c48SPeter Maydell  * this list of conditions and the following disclaimer.
5616017c48SPeter Maydell  *
5716017c48SPeter Maydell  * 2. Redistributions in binary form must reproduce the above copyright notice,
5816017c48SPeter Maydell  * this list of conditions and the following disclaimer in the documentation
5916017c48SPeter Maydell  * and/or other materials provided with the distribution.
6016017c48SPeter Maydell  *
6116017c48SPeter Maydell  * 3. Neither the name of the copyright holder nor the names of its contributors
6216017c48SPeter Maydell  * may be used to endorse or promote products derived from this software without
6316017c48SPeter Maydell  * specific prior written permission.
6416017c48SPeter Maydell  *
6516017c48SPeter Maydell  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
6616017c48SPeter Maydell  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6716017c48SPeter Maydell  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
6816017c48SPeter Maydell  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
6916017c48SPeter Maydell  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
7016017c48SPeter Maydell  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
7116017c48SPeter Maydell  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
7216017c48SPeter Maydell  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
7316017c48SPeter Maydell  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
7416017c48SPeter Maydell  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
7516017c48SPeter Maydell  * THE POSSIBILITY OF SUCH DAMAGE.
7616017c48SPeter Maydell  */
7716017c48SPeter Maydell 
7816017c48SPeter Maydell /* Portions of this work are licensed under the terms of the GNU GPL,
7916017c48SPeter Maydell  * version 2 or later. See the COPYING file in the top-level directory.
8016017c48SPeter Maydell  */
8116017c48SPeter Maydell 
826b4c305cSPaolo Bonzini #ifndef SOFTFLOAT_H
836b4c305cSPaolo Bonzini #define SOFTFLOAT_H
846b4c305cSPaolo Bonzini 
856b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
866b4c305cSPaolo Bonzini | Software IEC/IEEE floating-point ordering relations
876b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
8871bfd65cSRichard Henderson 
8971bfd65cSRichard Henderson typedef enum {
906b4c305cSPaolo Bonzini     float_relation_less      = -1,
916b4c305cSPaolo Bonzini     float_relation_equal     =  0,
926b4c305cSPaolo Bonzini     float_relation_greater   =  1,
936b4c305cSPaolo Bonzini     float_relation_unordered =  2
9471bfd65cSRichard Henderson } FloatRelation;
956b4c305cSPaolo Bonzini 
96cfd88fc6SAlex Bennée #include "fpu/softfloat-types.h"
97e34c47eaSAlex Bennée #include "fpu/softfloat-helpers.h"
98f279852bSMatheus Ferst #include "qemu/int128.h"
996b4c305cSPaolo Bonzini 
1006b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1016b4c305cSPaolo Bonzini | Routine to raise any or all of the software IEC/IEEE floating-point
1026b4c305cSPaolo Bonzini | exception flags.
1036b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
float_raise(uint16_t flags,float_status * status)104149a48f6SRichard Henderson static inline void float_raise(uint16_t flags, float_status *status)
105622090aeSRichard Henderson {
106622090aeSRichard Henderson     status->float_exception_flags |= flags;
107622090aeSRichard Henderson }
1086b4c305cSPaolo Bonzini 
1096b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1107baeabceSAlex Bennée | If `a' is denormal and we are in flush-to-zero mode then set the
1117baeabceSAlex Bennée | input-denormal exception and return zero. Otherwise just return the value.
1127baeabceSAlex Bennée *----------------------------------------------------------------------------*/
113210cbd49SAlex Bennée float16 float16_squash_input_denormal(float16 a, float_status *status);
114e5a41ffaSPeter Maydell float32 float32_squash_input_denormal(float32 a, float_status *status);
115e5a41ffaSPeter Maydell float64 float64_squash_input_denormal(float64 a, float_status *status);
1168282310dSLIU Zhiwei bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status);
1177baeabceSAlex Bennée 
1187baeabceSAlex Bennée /*----------------------------------------------------------------------------
1196b4c305cSPaolo Bonzini | Options to indicate which negations to perform in float*_muladd()
1206b4c305cSPaolo Bonzini | Using these differs from negating an input or output before calling
1216b4c305cSPaolo Bonzini | the muladd function in that this means that a NaN doesn't have its
1226b4c305cSPaolo Bonzini | sign bit inverted before it is propagated.
12367d43538SPeter Maydell | We also support halving the result before rounding, as a special
12467d43538SPeter Maydell | case to support the ARM fused-sqrt-step instruction FRSQRTS.
1256b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1266b4c305cSPaolo Bonzini enum {
1276b4c305cSPaolo Bonzini     float_muladd_negate_c = 1,
1286b4c305cSPaolo Bonzini     float_muladd_negate_product = 2,
1296b4c305cSPaolo Bonzini     float_muladd_negate_result = 4,
13067d43538SPeter Maydell     float_muladd_halve_result = 8,
1316b4c305cSPaolo Bonzini };
1326b4c305cSPaolo Bonzini 
1336b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1346b4c305cSPaolo Bonzini | Software IEC/IEEE integer-to-floating-point conversion routines.
1356b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1362abdfe24SRichard Henderson 
1372abdfe24SRichard Henderson float16 int16_to_float16_scalbn(int16_t a, int, float_status *status);
1382abdfe24SRichard Henderson float16 int32_to_float16_scalbn(int32_t a, int, float_status *status);
1392abdfe24SRichard Henderson float16 int64_to_float16_scalbn(int64_t a, int, float_status *status);
1402abdfe24SRichard Henderson float16 uint16_to_float16_scalbn(uint16_t a, int, float_status *status);
1412abdfe24SRichard Henderson float16 uint32_to_float16_scalbn(uint32_t a, int, float_status *status);
1422abdfe24SRichard Henderson float16 uint64_to_float16_scalbn(uint64_t a, int, float_status *status);
1432abdfe24SRichard Henderson 
1440d93d8ecSFrank Chang float16 int8_to_float16(int8_t a, float_status *status);
1452abdfe24SRichard Henderson float16 int16_to_float16(int16_t a, float_status *status);
1462abdfe24SRichard Henderson float16 int32_to_float16(int32_t a, float_status *status);
1472abdfe24SRichard Henderson float16 int64_to_float16(int64_t a, float_status *status);
1480d93d8ecSFrank Chang float16 uint8_to_float16(uint8_t a, float_status *status);
1492abdfe24SRichard Henderson float16 uint16_to_float16(uint16_t a, float_status *status);
1502abdfe24SRichard Henderson float16 uint32_to_float16(uint32_t a, float_status *status);
1512abdfe24SRichard Henderson float16 uint64_to_float16(uint64_t a, float_status *status);
1522abdfe24SRichard Henderson 
1532abdfe24SRichard Henderson float32 int16_to_float32_scalbn(int16_t, int, float_status *status);
1542abdfe24SRichard Henderson float32 int32_to_float32_scalbn(int32_t, int, float_status *status);
1552abdfe24SRichard Henderson float32 int64_to_float32_scalbn(int64_t, int, float_status *status);
1562abdfe24SRichard Henderson float32 uint16_to_float32_scalbn(uint16_t, int, float_status *status);
1572abdfe24SRichard Henderson float32 uint32_to_float32_scalbn(uint32_t, int, float_status *status);
1582abdfe24SRichard Henderson float32 uint64_to_float32_scalbn(uint64_t, int, float_status *status);
1592abdfe24SRichard Henderson 
160c02e1fb8SAlex Bennée float32 int16_to_float32(int16_t, float_status *status);
161e5a41ffaSPeter Maydell float32 int32_to_float32(int32_t, float_status *status);
1622abdfe24SRichard Henderson float32 int64_to_float32(int64_t, float_status *status);
163c02e1fb8SAlex Bennée float32 uint16_to_float32(uint16_t, float_status *status);
164e5a41ffaSPeter Maydell float32 uint32_to_float32(uint32_t, float_status *status);
1652abdfe24SRichard Henderson float32 uint64_to_float32(uint64_t, float_status *status);
1662abdfe24SRichard Henderson 
1672abdfe24SRichard Henderson float64 int16_to_float64_scalbn(int16_t, int, float_status *status);
1682abdfe24SRichard Henderson float64 int32_to_float64_scalbn(int32_t, int, float_status *status);
1692abdfe24SRichard Henderson float64 int64_to_float64_scalbn(int64_t, int, float_status *status);
1702abdfe24SRichard Henderson float64 uint16_to_float64_scalbn(uint16_t, int, float_status *status);
1712abdfe24SRichard Henderson float64 uint32_to_float64_scalbn(uint32_t, int, float_status *status);
1722abdfe24SRichard Henderson float64 uint64_to_float64_scalbn(uint64_t, int, float_status *status);
1732abdfe24SRichard Henderson 
1742abdfe24SRichard Henderson float64 int16_to_float64(int16_t, float_status *status);
1752abdfe24SRichard Henderson float64 int32_to_float64(int32_t, float_status *status);
1762abdfe24SRichard Henderson float64 int64_to_float64(int64_t, float_status *status);
177c02e1fb8SAlex Bennée float64 uint16_to_float64(uint16_t, float_status *status);
178e5a41ffaSPeter Maydell float64 uint32_to_float64(uint32_t, float_status *status);
179e5a41ffaSPeter Maydell float64 uint64_to_float64(uint64_t, float_status *status);
1802abdfe24SRichard Henderson 
1812abdfe24SRichard Henderson floatx80 int32_to_floatx80(int32_t, float_status *status);
1822abdfe24SRichard Henderson floatx80 int64_to_floatx80(int64_t, float_status *status);
1832abdfe24SRichard Henderson 
1842abdfe24SRichard Henderson float128 int32_to_float128(int32_t, float_status *status);
1852abdfe24SRichard Henderson float128 int64_to_float128(int64_t, float_status *status);
18695c1b71eSMatheus Ferst float128 int128_to_float128(Int128, float_status *status);
187e5a41ffaSPeter Maydell float128 uint64_to_float128(uint64_t, float_status *status);
188f279852bSMatheus Ferst float128 uint128_to_float128(Int128, float_status *status);
1896b4c305cSPaolo Bonzini 
1906b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1916b4c305cSPaolo Bonzini | Software half-precision conversion routines.
1926b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1932f6c74beSRichard Henderson 
1946fed16b2SAlex Bennée float16 float32_to_float16(float32, bool ieee, float_status *status);
1956fed16b2SAlex Bennée float32 float16_to_float32(float16, bool ieee, float_status *status);
1966fed16b2SAlex Bennée float16 float64_to_float16(float64 a, bool ieee, float_status *status);
1976fed16b2SAlex Bennée float64 float16_to_float64(float16 a, bool ieee, float_status *status);
1982f6c74beSRichard Henderson 
1990d93d8ecSFrank Chang int8_t  float16_to_int8_scalbn(float16, FloatRoundMode, int,
2000d93d8ecSFrank Chang                                float_status *status);
2013dede407SRichard Henderson int16_t float16_to_int16_scalbn(float16, FloatRoundMode, int, float_status *);
2023dede407SRichard Henderson int32_t float16_to_int32_scalbn(float16, FloatRoundMode, int, float_status *);
2033dede407SRichard Henderson int64_t float16_to_int64_scalbn(float16, FloatRoundMode, int, float_status *);
2042f6c74beSRichard Henderson 
2050d93d8ecSFrank Chang int8_t  float16_to_int8(float16, float_status *status);
206ab52f973SAlex Bennée int16_t float16_to_int16(float16, float_status *status);
207ab52f973SAlex Bennée int32_t float16_to_int32(float16, float_status *status);
208ab52f973SAlex Bennée int64_t float16_to_int64(float16, float_status *status);
2092f6c74beSRichard Henderson 
2102f6c74beSRichard Henderson int16_t float16_to_int16_round_to_zero(float16, float_status *status);
2112f6c74beSRichard Henderson int32_t float16_to_int32_round_to_zero(float16, float_status *status);
212ab52f973SAlex Bennée int64_t float16_to_int64_round_to_zero(float16, float_status *status);
2132f6c74beSRichard Henderson 
2140d93d8ecSFrank Chang uint8_t float16_to_uint8_scalbn(float16 a, FloatRoundMode,
2150d93d8ecSFrank Chang                                 int, float_status *status);
2163dede407SRichard Henderson uint16_t float16_to_uint16_scalbn(float16 a, FloatRoundMode,
2173dede407SRichard Henderson                                   int, float_status *status);
2183dede407SRichard Henderson uint32_t float16_to_uint32_scalbn(float16 a, FloatRoundMode,
2193dede407SRichard Henderson                                   int, float_status *status);
2203dede407SRichard Henderson uint64_t float16_to_uint64_scalbn(float16 a, FloatRoundMode,
2213dede407SRichard Henderson                                   int, float_status *status);
2222f6c74beSRichard Henderson 
2230d93d8ecSFrank Chang uint8_t  float16_to_uint8(float16 a, float_status *status);
2242f6c74beSRichard Henderson uint16_t float16_to_uint16(float16 a, float_status *status);
2252f6c74beSRichard Henderson uint32_t float16_to_uint32(float16 a, float_status *status);
2262f6c74beSRichard Henderson uint64_t float16_to_uint64(float16 a, float_status *status);
2272f6c74beSRichard Henderson 
2282f6c74beSRichard Henderson uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status);
2292f6c74beSRichard Henderson uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status);
230ab52f973SAlex Bennée uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status);
2316b4c305cSPaolo Bonzini 
2326b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
2336b4c305cSPaolo Bonzini | Software half-precision operations.
2346b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
2356fff2167SAlex Bennée 
236dbe4d53aSAlex Bennée float16 float16_round_to_int(float16, float_status *status);
2376fff2167SAlex Bennée float16 float16_add(float16, float16, float_status *status);
2386fff2167SAlex Bennée float16 float16_sub(float16, float16, float_status *status);
23974d707e2SAlex Bennée float16 float16_mul(float16, float16, float_status *status);
240d446830aSAlex Bennée float16 float16_muladd(float16, float16, float16, int, float_status *status);
241cf07323dSAlex Bennée float16 float16_div(float16, float16, float_status *status);
2420bfc9f19SAlex Bennée float16 float16_scalbn(float16, int, float_status *status);
24389360067SAlex Bennée float16 float16_min(float16, float16, float_status *status);
24489360067SAlex Bennée float16 float16_max(float16, float16, float_status *status);
24589360067SAlex Bennée float16 float16_minnum(float16, float16, float_status *status);
24689360067SAlex Bennée float16 float16_maxnum(float16, float16, float_status *status);
24789360067SAlex Bennée float16 float16_minnummag(float16, float16, float_status *status);
24889360067SAlex Bennée float16 float16_maxnummag(float16, float16, float_status *status);
2490e903037SChih-Min Chao float16 float16_minimum_number(float16, float16, float_status *status);
2500e903037SChih-Min Chao float16 float16_maximum_number(float16, float16, float_status *status);
251c13bb2daSAlex Bennée float16 float16_sqrt(float16, float_status *status);
25271bfd65cSRichard Henderson FloatRelation float16_compare(float16, float16, float_status *status);
25371bfd65cSRichard Henderson FloatRelation float16_compare_quiet(float16, float16, float_status *status);
2546fff2167SAlex Bennée 
255150c7a91SRichard Henderson bool float16_is_quiet_nan(float16, float_status *status);
256150c7a91SRichard Henderson bool float16_is_signaling_nan(float16, float_status *status);
257d619bb98SRichard Henderson float16 float16_silence_nan(float16, float_status *status);
2586b4c305cSPaolo Bonzini 
float16_is_any_nan(float16 a)259150c7a91SRichard Henderson static inline bool float16_is_any_nan(float16 a)
2606b4c305cSPaolo Bonzini {
2616b4c305cSPaolo Bonzini     return ((float16_val(a) & ~0x8000) > 0x7c00);
2626b4c305cSPaolo Bonzini }
2636b4c305cSPaolo Bonzini 
float16_is_neg(float16 a)264150c7a91SRichard Henderson static inline bool float16_is_neg(float16 a)
265f566c047SBharata B Rao {
266f566c047SBharata B Rao     return float16_val(a) >> 15;
267f566c047SBharata B Rao }
268f566c047SBharata B Rao 
float16_is_infinity(float16 a)269150c7a91SRichard Henderson static inline bool float16_is_infinity(float16 a)
270f566c047SBharata B Rao {
271f566c047SBharata B Rao     return (float16_val(a) & 0x7fff) == 0x7c00;
272f566c047SBharata B Rao }
273f566c047SBharata B Rao 
float16_is_zero(float16 a)274150c7a91SRichard Henderson static inline bool float16_is_zero(float16 a)
275f566c047SBharata B Rao {
276f566c047SBharata B Rao     return (float16_val(a) & 0x7fff) == 0;
277f566c047SBharata B Rao }
278f566c047SBharata B Rao 
float16_is_zero_or_denormal(float16 a)279150c7a91SRichard Henderson static inline bool float16_is_zero_or_denormal(float16 a)
280f566c047SBharata B Rao {
281f566c047SBharata B Rao     return (float16_val(a) & 0x7c00) == 0;
282f566c047SBharata B Rao }
283f566c047SBharata B Rao 
float16_is_normal(float16 a)284a03e924cSStephen Long static inline bool float16_is_normal(float16 a)
285a03e924cSStephen Long {
286a03e924cSStephen Long     return (((float16_val(a) >> 10) + 1) & 0x1f) >= 2;
287a03e924cSStephen Long }
288a03e924cSStephen Long 
float16_abs(float16 a)28928136775SAlex Bennée static inline float16 float16_abs(float16 a)
29028136775SAlex Bennée {
29128136775SAlex Bennée     /* Note that abs does *not* handle NaN specially, nor does
29228136775SAlex Bennée      * it flush denormal inputs to zero.
29328136775SAlex Bennée      */
29428136775SAlex Bennée     return make_float16(float16_val(a) & 0x7fff);
29528136775SAlex Bennée }
2965f10aef5SAlex Bennée 
float16_chs(float16 a)2975f10aef5SAlex Bennée static inline float16 float16_chs(float16 a)
2985f10aef5SAlex Bennée {
2995f10aef5SAlex Bennée     /* Note that chs does *not* handle NaN specially, nor does
3005f10aef5SAlex Bennée      * it flush denormal inputs to zero.
3015f10aef5SAlex Bennée      */
3025f10aef5SAlex Bennée     return make_float16(float16_val(a) ^ 0x8000);
3035f10aef5SAlex Bennée }
3045f10aef5SAlex Bennée 
float16_set_sign(float16 a,int sign)30578b5a3e6SAlex Bennée static inline float16 float16_set_sign(float16 a, int sign)
30678b5a3e6SAlex Bennée {
30778b5a3e6SAlex Bennée     return make_float16((float16_val(a) & 0x7fff) | (sign << 15));
30878b5a3e6SAlex Bennée }
30978b5a3e6SAlex Bennée 
float16_eq(float16 a,float16 b,float_status * s)310dd205025SKito Cheng static inline bool float16_eq(float16 a, float16 b, float_status *s)
311dd205025SKito Cheng {
312dd205025SKito Cheng     return float16_compare(a, b, s) == float_relation_equal;
313dd205025SKito Cheng }
314dd205025SKito Cheng 
float16_le(float16 a,float16 b,float_status * s)315dd205025SKito Cheng static inline bool float16_le(float16 a, float16 b, float_status *s)
316dd205025SKito Cheng {
317dd205025SKito Cheng     return float16_compare(a, b, s) <= float_relation_equal;
318dd205025SKito Cheng }
319dd205025SKito Cheng 
float16_lt(float16 a,float16 b,float_status * s)320dd205025SKito Cheng static inline bool float16_lt(float16 a, float16 b, float_status *s)
321dd205025SKito Cheng {
322dd205025SKito Cheng     return float16_compare(a, b, s) < float_relation_equal;
323dd205025SKito Cheng }
324dd205025SKito Cheng 
float16_unordered(float16 a,float16 b,float_status * s)325dd205025SKito Cheng static inline bool float16_unordered(float16 a, float16 b, float_status *s)
326dd205025SKito Cheng {
327dd205025SKito Cheng     return float16_compare(a, b, s) == float_relation_unordered;
328dd205025SKito Cheng }
329dd205025SKito Cheng 
float16_eq_quiet(float16 a,float16 b,float_status * s)330dd205025SKito Cheng static inline bool float16_eq_quiet(float16 a, float16 b, float_status *s)
331dd205025SKito Cheng {
332dd205025SKito Cheng     return float16_compare_quiet(a, b, s) == float_relation_equal;
333dd205025SKito Cheng }
334dd205025SKito Cheng 
float16_le_quiet(float16 a,float16 b,float_status * s)335dd205025SKito Cheng static inline bool float16_le_quiet(float16 a, float16 b, float_status *s)
336dd205025SKito Cheng {
337dd205025SKito Cheng     return float16_compare_quiet(a, b, s) <= float_relation_equal;
338dd205025SKito Cheng }
339dd205025SKito Cheng 
float16_lt_quiet(float16 a,float16 b,float_status * s)340dd205025SKito Cheng static inline bool float16_lt_quiet(float16 a, float16 b, float_status *s)
341dd205025SKito Cheng {
342dd205025SKito Cheng     return float16_compare_quiet(a, b, s) < float_relation_equal;
343dd205025SKito Cheng }
344dd205025SKito Cheng 
float16_unordered_quiet(float16 a,float16 b,float_status * s)345dd205025SKito Cheng static inline bool float16_unordered_quiet(float16 a, float16 b,
346dd205025SKito Cheng                                            float_status *s)
347dd205025SKito Cheng {
348dd205025SKito Cheng     return float16_compare_quiet(a, b, s) == float_relation_unordered;
349dd205025SKito Cheng }
350dd205025SKito Cheng 
351efd4829eSAlex Bennée #define float16_zero make_float16(0)
352efd4829eSAlex Bennée #define float16_half make_float16(0x3800)
353026e2d6eSAlex Bennée #define float16_one make_float16(0x3c00)
354026e2d6eSAlex Bennée #define float16_one_point_five make_float16(0x3e00)
355026e2d6eSAlex Bennée #define float16_two make_float16(0x4000)
356026e2d6eSAlex Bennée #define float16_three make_float16(0x4200)
357efd4829eSAlex Bennée #define float16_infinity make_float16(0x7c00)
358efd4829eSAlex Bennée 
3596b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
36034f0c0a9SLIU Zhiwei | Software bfloat16 conversion routines.
36134f0c0a9SLIU Zhiwei *----------------------------------------------------------------------------*/
36234f0c0a9SLIU Zhiwei 
36334f0c0a9SLIU Zhiwei bfloat16 bfloat16_round_to_int(bfloat16, float_status *status);
36434f0c0a9SLIU Zhiwei bfloat16 float32_to_bfloat16(float32, float_status *status);
36534f0c0a9SLIU Zhiwei float32 bfloat16_to_float32(bfloat16, float_status *status);
36634f0c0a9SLIU Zhiwei bfloat16 float64_to_bfloat16(float64 a, float_status *status);
36734f0c0a9SLIU Zhiwei float64 bfloat16_to_float64(bfloat16 a, float_status *status);
36834f0c0a9SLIU Zhiwei 
36900f9ef8fSLIU Zhiwei int8_t bfloat16_to_int8_scalbn(bfloat16, FloatRoundMode,
37000f9ef8fSLIU Zhiwei                                int, float_status *status);
37134f0c0a9SLIU Zhiwei int16_t bfloat16_to_int16_scalbn(bfloat16, FloatRoundMode,
37234f0c0a9SLIU Zhiwei                                  int, float_status *status);
37334f0c0a9SLIU Zhiwei int32_t bfloat16_to_int32_scalbn(bfloat16, FloatRoundMode,
37434f0c0a9SLIU Zhiwei                                  int, float_status *status);
37534f0c0a9SLIU Zhiwei int64_t bfloat16_to_int64_scalbn(bfloat16, FloatRoundMode,
37634f0c0a9SLIU Zhiwei                                  int, float_status *status);
37734f0c0a9SLIU Zhiwei 
37800f9ef8fSLIU Zhiwei int8_t bfloat16_to_int8(bfloat16, float_status *status);
37934f0c0a9SLIU Zhiwei int16_t bfloat16_to_int16(bfloat16, float_status *status);
38034f0c0a9SLIU Zhiwei int32_t bfloat16_to_int32(bfloat16, float_status *status);
38134f0c0a9SLIU Zhiwei int64_t bfloat16_to_int64(bfloat16, float_status *status);
38234f0c0a9SLIU Zhiwei 
38300f9ef8fSLIU Zhiwei int8_t bfloat16_to_int8_round_to_zero(bfloat16, float_status *status);
38434f0c0a9SLIU Zhiwei int16_t bfloat16_to_int16_round_to_zero(bfloat16, float_status *status);
38534f0c0a9SLIU Zhiwei int32_t bfloat16_to_int32_round_to_zero(bfloat16, float_status *status);
38634f0c0a9SLIU Zhiwei int64_t bfloat16_to_int64_round_to_zero(bfloat16, float_status *status);
38734f0c0a9SLIU Zhiwei 
38800f9ef8fSLIU Zhiwei uint8_t bfloat16_to_uint8_scalbn(bfloat16 a, FloatRoundMode,
38900f9ef8fSLIU Zhiwei                                  int, float_status *status);
39034f0c0a9SLIU Zhiwei uint16_t bfloat16_to_uint16_scalbn(bfloat16 a, FloatRoundMode,
39134f0c0a9SLIU Zhiwei                                    int, float_status *status);
39234f0c0a9SLIU Zhiwei uint32_t bfloat16_to_uint32_scalbn(bfloat16 a, FloatRoundMode,
39334f0c0a9SLIU Zhiwei                                    int, float_status *status);
39434f0c0a9SLIU Zhiwei uint64_t bfloat16_to_uint64_scalbn(bfloat16 a, FloatRoundMode,
39534f0c0a9SLIU Zhiwei                                    int, float_status *status);
39634f0c0a9SLIU Zhiwei 
39700f9ef8fSLIU Zhiwei uint8_t bfloat16_to_uint8(bfloat16 a, float_status *status);
39834f0c0a9SLIU Zhiwei uint16_t bfloat16_to_uint16(bfloat16 a, float_status *status);
39934f0c0a9SLIU Zhiwei uint32_t bfloat16_to_uint32(bfloat16 a, float_status *status);
40034f0c0a9SLIU Zhiwei uint64_t bfloat16_to_uint64(bfloat16 a, float_status *status);
40134f0c0a9SLIU Zhiwei 
40200f9ef8fSLIU Zhiwei uint8_t bfloat16_to_uint8_round_to_zero(bfloat16 a, float_status *status);
40334f0c0a9SLIU Zhiwei uint16_t bfloat16_to_uint16_round_to_zero(bfloat16 a, float_status *status);
40434f0c0a9SLIU Zhiwei uint32_t bfloat16_to_uint32_round_to_zero(bfloat16 a, float_status *status);
40534f0c0a9SLIU Zhiwei uint64_t bfloat16_to_uint64_round_to_zero(bfloat16 a, float_status *status);
40634f0c0a9SLIU Zhiwei 
40700f9ef8fSLIU Zhiwei bfloat16 int8_to_bfloat16_scalbn(int8_t a, int, float_status *status);
40834f0c0a9SLIU Zhiwei bfloat16 int16_to_bfloat16_scalbn(int16_t a, int, float_status *status);
40934f0c0a9SLIU Zhiwei bfloat16 int32_to_bfloat16_scalbn(int32_t a, int, float_status *status);
41034f0c0a9SLIU Zhiwei bfloat16 int64_to_bfloat16_scalbn(int64_t a, int, float_status *status);
41100f9ef8fSLIU Zhiwei bfloat16 uint8_to_bfloat16_scalbn(uint8_t a, int, float_status *status);
41234f0c0a9SLIU Zhiwei bfloat16 uint16_to_bfloat16_scalbn(uint16_t a, int, float_status *status);
41334f0c0a9SLIU Zhiwei bfloat16 uint32_to_bfloat16_scalbn(uint32_t a, int, float_status *status);
41434f0c0a9SLIU Zhiwei bfloat16 uint64_to_bfloat16_scalbn(uint64_t a, int, float_status *status);
41534f0c0a9SLIU Zhiwei 
41600f9ef8fSLIU Zhiwei bfloat16 int8_to_bfloat16(int8_t a, float_status *status);
41734f0c0a9SLIU Zhiwei bfloat16 int16_to_bfloat16(int16_t a, float_status *status);
41834f0c0a9SLIU Zhiwei bfloat16 int32_to_bfloat16(int32_t a, float_status *status);
41934f0c0a9SLIU Zhiwei bfloat16 int64_to_bfloat16(int64_t a, float_status *status);
42000f9ef8fSLIU Zhiwei bfloat16 uint8_to_bfloat16(uint8_t a, float_status *status);
42134f0c0a9SLIU Zhiwei bfloat16 uint16_to_bfloat16(uint16_t a, float_status *status);
42234f0c0a9SLIU Zhiwei bfloat16 uint32_to_bfloat16(uint32_t a, float_status *status);
42334f0c0a9SLIU Zhiwei bfloat16 uint64_to_bfloat16(uint64_t a, float_status *status);
42434f0c0a9SLIU Zhiwei 
42534f0c0a9SLIU Zhiwei /*----------------------------------------------------------------------------
4268282310dSLIU Zhiwei | Software bfloat16 operations.
4278282310dSLIU Zhiwei *----------------------------------------------------------------------------*/
4288282310dSLIU Zhiwei 
4298282310dSLIU Zhiwei bfloat16 bfloat16_add(bfloat16, bfloat16, float_status *status);
4308282310dSLIU Zhiwei bfloat16 bfloat16_sub(bfloat16, bfloat16, float_status *status);
4318282310dSLIU Zhiwei bfloat16 bfloat16_mul(bfloat16, bfloat16, float_status *status);
4328282310dSLIU Zhiwei bfloat16 bfloat16_div(bfloat16, bfloat16, float_status *status);
4338282310dSLIU Zhiwei bfloat16 bfloat16_muladd(bfloat16, bfloat16, bfloat16, int,
4348282310dSLIU Zhiwei                          float_status *status);
4358282310dSLIU Zhiwei float16 bfloat16_scalbn(bfloat16, int, float_status *status);
4368282310dSLIU Zhiwei bfloat16 bfloat16_min(bfloat16, bfloat16, float_status *status);
4378282310dSLIU Zhiwei bfloat16 bfloat16_max(bfloat16, bfloat16, float_status *status);
4388282310dSLIU Zhiwei bfloat16 bfloat16_minnum(bfloat16, bfloat16, float_status *status);
4398282310dSLIU Zhiwei bfloat16 bfloat16_maxnum(bfloat16, bfloat16, float_status *status);
4408282310dSLIU Zhiwei bfloat16 bfloat16_minnummag(bfloat16, bfloat16, float_status *status);
4418282310dSLIU Zhiwei bfloat16 bfloat16_maxnummag(bfloat16, bfloat16, float_status *status);
4420e903037SChih-Min Chao bfloat16 bfloat16_minimum_number(bfloat16, bfloat16, float_status *status);
4430e903037SChih-Min Chao bfloat16 bfloat16_maximum_number(bfloat16, bfloat16, float_status *status);
4448282310dSLIU Zhiwei bfloat16 bfloat16_sqrt(bfloat16, float_status *status);
4458282310dSLIU Zhiwei FloatRelation bfloat16_compare(bfloat16, bfloat16, float_status *status);
4468282310dSLIU Zhiwei FloatRelation bfloat16_compare_quiet(bfloat16, bfloat16, float_status *status);
4478282310dSLIU Zhiwei 
4485ebf5f4bSLIU Zhiwei bool bfloat16_is_quiet_nan(bfloat16, float_status *status);
4495ebf5f4bSLIU Zhiwei bool bfloat16_is_signaling_nan(bfloat16, float_status *status);
4508282310dSLIU Zhiwei bfloat16 bfloat16_silence_nan(bfloat16, float_status *status);
4518282310dSLIU Zhiwei bfloat16 bfloat16_default_nan(float_status *status);
4528282310dSLIU Zhiwei 
bfloat16_is_any_nan(bfloat16 a)4535ebf5f4bSLIU Zhiwei static inline bool bfloat16_is_any_nan(bfloat16 a)
4545ebf5f4bSLIU Zhiwei {
4555ebf5f4bSLIU Zhiwei     return ((a & ~0x8000) > 0x7F80);
4565ebf5f4bSLIU Zhiwei }
4575ebf5f4bSLIU Zhiwei 
bfloat16_is_neg(bfloat16 a)4585ebf5f4bSLIU Zhiwei static inline bool bfloat16_is_neg(bfloat16 a)
4595ebf5f4bSLIU Zhiwei {
4605ebf5f4bSLIU Zhiwei     return a >> 15;
4615ebf5f4bSLIU Zhiwei }
4625ebf5f4bSLIU Zhiwei 
bfloat16_is_infinity(bfloat16 a)4635ebf5f4bSLIU Zhiwei static inline bool bfloat16_is_infinity(bfloat16 a)
4645ebf5f4bSLIU Zhiwei {
4655ebf5f4bSLIU Zhiwei     return (a & 0x7fff) == 0x7F80;
4665ebf5f4bSLIU Zhiwei }
4675ebf5f4bSLIU Zhiwei 
bfloat16_is_zero(bfloat16 a)4685ebf5f4bSLIU Zhiwei static inline bool bfloat16_is_zero(bfloat16 a)
4695ebf5f4bSLIU Zhiwei {
4705ebf5f4bSLIU Zhiwei     return (a & 0x7fff) == 0;
4715ebf5f4bSLIU Zhiwei }
4725ebf5f4bSLIU Zhiwei 
bfloat16_is_zero_or_denormal(bfloat16 a)4735ebf5f4bSLIU Zhiwei static inline bool bfloat16_is_zero_or_denormal(bfloat16 a)
4745ebf5f4bSLIU Zhiwei {
4755ebf5f4bSLIU Zhiwei     return (a & 0x7F80) == 0;
4765ebf5f4bSLIU Zhiwei }
4775ebf5f4bSLIU Zhiwei 
bfloat16_is_normal(bfloat16 a)4785ebf5f4bSLIU Zhiwei static inline bool bfloat16_is_normal(bfloat16 a)
4795ebf5f4bSLIU Zhiwei {
4805ebf5f4bSLIU Zhiwei     return (((a >> 7) + 1) & 0xff) >= 2;
4815ebf5f4bSLIU Zhiwei }
4825ebf5f4bSLIU Zhiwei 
bfloat16_abs(bfloat16 a)4835ebf5f4bSLIU Zhiwei static inline bfloat16 bfloat16_abs(bfloat16 a)
4845ebf5f4bSLIU Zhiwei {
4855ebf5f4bSLIU Zhiwei     /* Note that abs does *not* handle NaN specially, nor does
4865ebf5f4bSLIU Zhiwei      * it flush denormal inputs to zero.
4875ebf5f4bSLIU Zhiwei      */
4885ebf5f4bSLIU Zhiwei     return a & 0x7fff;
4895ebf5f4bSLIU Zhiwei }
4905ebf5f4bSLIU Zhiwei 
bfloat16_chs(bfloat16 a)4915ebf5f4bSLIU Zhiwei static inline bfloat16 bfloat16_chs(bfloat16 a)
4925ebf5f4bSLIU Zhiwei {
4935ebf5f4bSLIU Zhiwei     /* Note that chs does *not* handle NaN specially, nor does
4945ebf5f4bSLIU Zhiwei      * it flush denormal inputs to zero.
4955ebf5f4bSLIU Zhiwei      */
4965ebf5f4bSLIU Zhiwei     return a ^ 0x8000;
4975ebf5f4bSLIU Zhiwei }
4985ebf5f4bSLIU Zhiwei 
bfloat16_set_sign(bfloat16 a,int sign)4998282310dSLIU Zhiwei static inline bfloat16 bfloat16_set_sign(bfloat16 a, int sign)
5008282310dSLIU Zhiwei {
5018282310dSLIU Zhiwei     return (a & 0x7fff) | (sign << 15);
5028282310dSLIU Zhiwei }
5038282310dSLIU Zhiwei 
bfloat16_eq(bfloat16 a,bfloat16 b,float_status * s)504c53b1079SRichard Henderson static inline bool bfloat16_eq(bfloat16 a, bfloat16 b, float_status *s)
505c53b1079SRichard Henderson {
506c53b1079SRichard Henderson     return bfloat16_compare(a, b, s) == float_relation_equal;
507c53b1079SRichard Henderson }
508c53b1079SRichard Henderson 
bfloat16_le(bfloat16 a,bfloat16 b,float_status * s)509c53b1079SRichard Henderson static inline bool bfloat16_le(bfloat16 a, bfloat16 b, float_status *s)
510c53b1079SRichard Henderson {
511c53b1079SRichard Henderson     return bfloat16_compare(a, b, s) <= float_relation_equal;
512c53b1079SRichard Henderson }
513c53b1079SRichard Henderson 
bfloat16_lt(bfloat16 a,bfloat16 b,float_status * s)514c53b1079SRichard Henderson static inline bool bfloat16_lt(bfloat16 a, bfloat16 b, float_status *s)
515c53b1079SRichard Henderson {
516c53b1079SRichard Henderson     return bfloat16_compare(a, b, s) < float_relation_equal;
517c53b1079SRichard Henderson }
518c53b1079SRichard Henderson 
bfloat16_unordered(bfloat16 a,bfloat16 b,float_status * s)519c53b1079SRichard Henderson static inline bool bfloat16_unordered(bfloat16 a, bfloat16 b, float_status *s)
520c53b1079SRichard Henderson {
521c53b1079SRichard Henderson     return bfloat16_compare(a, b, s) == float_relation_unordered;
522c53b1079SRichard Henderson }
523c53b1079SRichard Henderson 
bfloat16_eq_quiet(bfloat16 a,bfloat16 b,float_status * s)524c53b1079SRichard Henderson static inline bool bfloat16_eq_quiet(bfloat16 a, bfloat16 b, float_status *s)
525c53b1079SRichard Henderson {
526c53b1079SRichard Henderson     return bfloat16_compare_quiet(a, b, s) == float_relation_equal;
527c53b1079SRichard Henderson }
528c53b1079SRichard Henderson 
bfloat16_le_quiet(bfloat16 a,bfloat16 b,float_status * s)529c53b1079SRichard Henderson static inline bool bfloat16_le_quiet(bfloat16 a, bfloat16 b, float_status *s)
530c53b1079SRichard Henderson {
531c53b1079SRichard Henderson     return bfloat16_compare_quiet(a, b, s) <= float_relation_equal;
532c53b1079SRichard Henderson }
533c53b1079SRichard Henderson 
bfloat16_lt_quiet(bfloat16 a,bfloat16 b,float_status * s)534c53b1079SRichard Henderson static inline bool bfloat16_lt_quiet(bfloat16 a, bfloat16 b, float_status *s)
535c53b1079SRichard Henderson {
536c53b1079SRichard Henderson     return bfloat16_compare_quiet(a, b, s) < float_relation_equal;
537c53b1079SRichard Henderson }
538c53b1079SRichard Henderson 
bfloat16_unordered_quiet(bfloat16 a,bfloat16 b,float_status * s)539c53b1079SRichard Henderson static inline bool bfloat16_unordered_quiet(bfloat16 a, bfloat16 b,
540c53b1079SRichard Henderson                                            float_status *s)
541c53b1079SRichard Henderson {
542c53b1079SRichard Henderson     return bfloat16_compare_quiet(a, b, s) == float_relation_unordered;
543c53b1079SRichard Henderson }
544c53b1079SRichard Henderson 
5458282310dSLIU Zhiwei #define bfloat16_zero 0
5468282310dSLIU Zhiwei #define bfloat16_half 0x3f00
5478282310dSLIU Zhiwei #define bfloat16_one 0x3f80
5488282310dSLIU Zhiwei #define bfloat16_one_point_five 0x3fc0
5498282310dSLIU Zhiwei #define bfloat16_two 0x4000
5508282310dSLIU Zhiwei #define bfloat16_three 0x4040
5518282310dSLIU Zhiwei #define bfloat16_infinity 0x7f80
5528282310dSLIU Zhiwei 
5538282310dSLIU Zhiwei /*----------------------------------------------------------------------------
5546b4c305cSPaolo Bonzini | The pattern for a default generated half-precision NaN.
5556b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
556af39bc8cSAleksandar Markovic float16 float16_default_nan(float_status *status);
5576b4c305cSPaolo Bonzini 
5586b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
5596b4c305cSPaolo Bonzini | Software IEC/IEEE single-precision conversion routines.
5606b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
5612f6c74beSRichard Henderson 
5623dede407SRichard Henderson int16_t float32_to_int16_scalbn(float32, FloatRoundMode, int, float_status *);
5633dede407SRichard Henderson int32_t float32_to_int32_scalbn(float32, FloatRoundMode, int, float_status *);
5643dede407SRichard Henderson int64_t float32_to_int64_scalbn(float32, FloatRoundMode, int, float_status *);
5652f6c74beSRichard Henderson 
5660bb721d7SPeter Maydell int16_t float32_to_int16(float32, float_status *status);
567f4014512SPeter Maydell int32_t float32_to_int32(float32, float_status *status);
568f42c2224SPeter Maydell int64_t float32_to_int64(float32, float_status *status);
5692f6c74beSRichard Henderson 
5702f6c74beSRichard Henderson int16_t float32_to_int16_round_to_zero(float32, float_status *status);
5712f6c74beSRichard Henderson int32_t float32_to_int32_round_to_zero(float32, float_status *status);
572f42c2224SPeter Maydell int64_t float32_to_int64_round_to_zero(float32, float_status *status);
5732f6c74beSRichard Henderson 
5743dede407SRichard Henderson uint16_t float32_to_uint16_scalbn(float32, FloatRoundMode, int, float_status *);
5753dede407SRichard Henderson uint32_t float32_to_uint32_scalbn(float32, FloatRoundMode, int, float_status *);
5763dede407SRichard Henderson uint64_t float32_to_uint64_scalbn(float32, FloatRoundMode, int, float_status *);
5772f6c74beSRichard Henderson 
5782f6c74beSRichard Henderson uint16_t float32_to_uint16(float32, float_status *status);
5792f6c74beSRichard Henderson uint32_t float32_to_uint32(float32, float_status *status);
5802f6c74beSRichard Henderson uint64_t float32_to_uint64(float32, float_status *status);
5812f6c74beSRichard Henderson 
5822f6c74beSRichard Henderson uint16_t float32_to_uint16_round_to_zero(float32, float_status *status);
5832f6c74beSRichard Henderson uint32_t float32_to_uint32_round_to_zero(float32, float_status *status);
5842f6c74beSRichard Henderson uint64_t float32_to_uint64_round_to_zero(float32, float_status *status);
5852f6c74beSRichard Henderson 
586e5a41ffaSPeter Maydell float64 float32_to_float64(float32, float_status *status);
587e5a41ffaSPeter Maydell floatx80 float32_to_floatx80(float32, float_status *status);
588e5a41ffaSPeter Maydell float128 float32_to_float128(float32, float_status *status);
5896b4c305cSPaolo Bonzini 
5906b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
5916b4c305cSPaolo Bonzini | Software IEC/IEEE single-precision operations.
5926b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
593e5a41ffaSPeter Maydell float32 float32_round_to_int(float32, float_status *status);
594e5a41ffaSPeter Maydell float32 float32_add(float32, float32, float_status *status);
595e5a41ffaSPeter Maydell float32 float32_sub(float32, float32, float_status *status);
596e5a41ffaSPeter Maydell float32 float32_mul(float32, float32, float_status *status);
597e5a41ffaSPeter Maydell float32 float32_div(float32, float32, float_status *status);
598e5a41ffaSPeter Maydell float32 float32_rem(float32, float32, float_status *status);
599e5a41ffaSPeter Maydell float32 float32_muladd(float32, float32, float32, int, float_status *status);
600e5a41ffaSPeter Maydell float32 float32_sqrt(float32, float_status *status);
601e5a41ffaSPeter Maydell float32 float32_exp2(float32, float_status *status);
602e5a41ffaSPeter Maydell float32 float32_log2(float32, float_status *status);
60371bfd65cSRichard Henderson FloatRelation float32_compare(float32, float32, float_status *status);
60471bfd65cSRichard Henderson FloatRelation float32_compare_quiet(float32, float32, float_status *status);
605e5a41ffaSPeter Maydell float32 float32_min(float32, float32, float_status *status);
606e5a41ffaSPeter Maydell float32 float32_max(float32, float32, float_status *status);
607e5a41ffaSPeter Maydell float32 float32_minnum(float32, float32, float_status *status);
608e5a41ffaSPeter Maydell float32 float32_maxnum(float32, float32, float_status *status);
609e5a41ffaSPeter Maydell float32 float32_minnummag(float32, float32, float_status *status);
610e5a41ffaSPeter Maydell float32 float32_maxnummag(float32, float32, float_status *status);
6110e903037SChih-Min Chao float32 float32_minimum_number(float32, float32, float_status *status);
6120e903037SChih-Min Chao float32 float32_maximum_number(float32, float32, float_status *status);
613150c7a91SRichard Henderson bool float32_is_quiet_nan(float32, float_status *status);
614150c7a91SRichard Henderson bool float32_is_signaling_nan(float32, float_status *status);
615d619bb98SRichard Henderson float32 float32_silence_nan(float32, float_status *status);
616e5a41ffaSPeter Maydell float32 float32_scalbn(float32, int, float_status *status);
6176b4c305cSPaolo Bonzini 
float32_abs(float32 a)618a49db98dSLuiz Capitulino static inline float32 float32_abs(float32 a)
6196b4c305cSPaolo Bonzini {
6206b4c305cSPaolo Bonzini     /* Note that abs does *not* handle NaN specially, nor does
6216b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
6226b4c305cSPaolo Bonzini      */
6236b4c305cSPaolo Bonzini     return make_float32(float32_val(a) & 0x7fffffff);
6246b4c305cSPaolo Bonzini }
6256b4c305cSPaolo Bonzini 
float32_chs(float32 a)626a49db98dSLuiz Capitulino static inline float32 float32_chs(float32 a)
6276b4c305cSPaolo Bonzini {
6286b4c305cSPaolo Bonzini     /* Note that chs does *not* handle NaN specially, nor does
6296b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
6306b4c305cSPaolo Bonzini      */
6316b4c305cSPaolo Bonzini     return make_float32(float32_val(a) ^ 0x80000000);
6326b4c305cSPaolo Bonzini }
6336b4c305cSPaolo Bonzini 
float32_is_infinity(float32 a)634150c7a91SRichard Henderson static inline bool float32_is_infinity(float32 a)
6356b4c305cSPaolo Bonzini {
6366b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7fffffff) == 0x7f800000;
6376b4c305cSPaolo Bonzini }
6386b4c305cSPaolo Bonzini 
float32_is_neg(float32 a)639150c7a91SRichard Henderson static inline bool float32_is_neg(float32 a)
6406b4c305cSPaolo Bonzini {
6416b4c305cSPaolo Bonzini     return float32_val(a) >> 31;
6426b4c305cSPaolo Bonzini }
6436b4c305cSPaolo Bonzini 
float32_is_zero(float32 a)644150c7a91SRichard Henderson static inline bool float32_is_zero(float32 a)
6456b4c305cSPaolo Bonzini {
6466b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7fffffff) == 0;
6476b4c305cSPaolo Bonzini }
6486b4c305cSPaolo Bonzini 
float32_is_any_nan(float32 a)649150c7a91SRichard Henderson static inline bool float32_is_any_nan(float32 a)
6506b4c305cSPaolo Bonzini {
6516b4c305cSPaolo Bonzini     return ((float32_val(a) & ~(1 << 31)) > 0x7f800000UL);
6526b4c305cSPaolo Bonzini }
6536b4c305cSPaolo Bonzini 
float32_is_zero_or_denormal(float32 a)654150c7a91SRichard Henderson static inline bool float32_is_zero_or_denormal(float32 a)
6556b4c305cSPaolo Bonzini {
6566b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7f800000) == 0;
6576b4c305cSPaolo Bonzini }
6586b4c305cSPaolo Bonzini 
float32_is_normal(float32 a)659588e6dfdSEmilio G. Cota static inline bool float32_is_normal(float32 a)
660588e6dfdSEmilio G. Cota {
66147393181SDavid Hildenbrand     return (((float32_val(a) >> 23) + 1) & 0xff) >= 2;
662588e6dfdSEmilio G. Cota }
663588e6dfdSEmilio G. Cota 
float32_is_denormal(float32 a)664588e6dfdSEmilio G. Cota static inline bool float32_is_denormal(float32 a)
665588e6dfdSEmilio G. Cota {
666588e6dfdSEmilio G. Cota     return float32_is_zero_or_denormal(a) && !float32_is_zero(a);
667588e6dfdSEmilio G. Cota }
668588e6dfdSEmilio G. Cota 
float32_is_zero_or_normal(float32 a)669315df0d1SEmilio G. Cota static inline bool float32_is_zero_or_normal(float32 a)
670315df0d1SEmilio G. Cota {
671315df0d1SEmilio G. Cota     return float32_is_normal(a) || float32_is_zero(a);
672315df0d1SEmilio G. Cota }
673315df0d1SEmilio G. Cota 
float32_set_sign(float32 a,int sign)674a49db98dSLuiz Capitulino static inline float32 float32_set_sign(float32 a, int sign)
6756b4c305cSPaolo Bonzini {
6766b4c305cSPaolo Bonzini     return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
6776b4c305cSPaolo Bonzini }
6786b4c305cSPaolo Bonzini 
float32_eq(float32 a,float32 b,float_status * s)6795da2d2d8SRichard Henderson static inline bool float32_eq(float32 a, float32 b, float_status *s)
6805da2d2d8SRichard Henderson {
6815da2d2d8SRichard Henderson     return float32_compare(a, b, s) == float_relation_equal;
6825da2d2d8SRichard Henderson }
6835da2d2d8SRichard Henderson 
float32_le(float32 a,float32 b,float_status * s)6845da2d2d8SRichard Henderson static inline bool float32_le(float32 a, float32 b, float_status *s)
6855da2d2d8SRichard Henderson {
6865da2d2d8SRichard Henderson     return float32_compare(a, b, s) <= float_relation_equal;
6875da2d2d8SRichard Henderson }
6885da2d2d8SRichard Henderson 
float32_lt(float32 a,float32 b,float_status * s)6895da2d2d8SRichard Henderson static inline bool float32_lt(float32 a, float32 b, float_status *s)
6905da2d2d8SRichard Henderson {
6915da2d2d8SRichard Henderson     return float32_compare(a, b, s) < float_relation_equal;
6925da2d2d8SRichard Henderson }
6935da2d2d8SRichard Henderson 
float32_unordered(float32 a,float32 b,float_status * s)6945da2d2d8SRichard Henderson static inline bool float32_unordered(float32 a, float32 b, float_status *s)
6955da2d2d8SRichard Henderson {
6965da2d2d8SRichard Henderson     return float32_compare(a, b, s) == float_relation_unordered;
6975da2d2d8SRichard Henderson }
6985da2d2d8SRichard Henderson 
float32_eq_quiet(float32 a,float32 b,float_status * s)6995da2d2d8SRichard Henderson static inline bool float32_eq_quiet(float32 a, float32 b, float_status *s)
7005da2d2d8SRichard Henderson {
7015da2d2d8SRichard Henderson     return float32_compare_quiet(a, b, s) == float_relation_equal;
7025da2d2d8SRichard Henderson }
7035da2d2d8SRichard Henderson 
float32_le_quiet(float32 a,float32 b,float_status * s)7045da2d2d8SRichard Henderson static inline bool float32_le_quiet(float32 a, float32 b, float_status *s)
7055da2d2d8SRichard Henderson {
7065da2d2d8SRichard Henderson     return float32_compare_quiet(a, b, s) <= float_relation_equal;
7075da2d2d8SRichard Henderson }
7085da2d2d8SRichard Henderson 
float32_lt_quiet(float32 a,float32 b,float_status * s)7095da2d2d8SRichard Henderson static inline bool float32_lt_quiet(float32 a, float32 b, float_status *s)
7105da2d2d8SRichard Henderson {
7115da2d2d8SRichard Henderson     return float32_compare_quiet(a, b, s) < float_relation_equal;
7125da2d2d8SRichard Henderson }
7135da2d2d8SRichard Henderson 
float32_unordered_quiet(float32 a,float32 b,float_status * s)7145da2d2d8SRichard Henderson static inline bool float32_unordered_quiet(float32 a, float32 b,
7155da2d2d8SRichard Henderson                                            float_status *s)
7165da2d2d8SRichard Henderson {
7175da2d2d8SRichard Henderson     return float32_compare_quiet(a, b, s) == float_relation_unordered;
7185da2d2d8SRichard Henderson }
7195da2d2d8SRichard Henderson 
7206b4c305cSPaolo Bonzini #define float32_zero make_float32(0)
7216b4c305cSPaolo Bonzini #define float32_half make_float32(0x3f000000)
722026e2d6eSAlex Bennée #define float32_one make_float32(0x3f800000)
723026e2d6eSAlex Bennée #define float32_one_point_five make_float32(0x3fc00000)
724026e2d6eSAlex Bennée #define float32_two make_float32(0x40000000)
725026e2d6eSAlex Bennée #define float32_three make_float32(0x40400000)
7266b4c305cSPaolo Bonzini #define float32_infinity make_float32(0x7f800000)
7276b4c305cSPaolo Bonzini 
7286b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
72988857acaSLaurent Vivier | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
73088857acaSLaurent Vivier | single-precision floating-point value, returning the result.  After being
73188857acaSLaurent Vivier | shifted into the proper positions, the three fields are simply added
73288857acaSLaurent Vivier | together to form the result.  This means that any integer portion of `zSig'
73388857acaSLaurent Vivier | will be added into the exponent.  Since a properly normalized significand
73488857acaSLaurent Vivier | will have an integer portion equal to 1, the `zExp' input should be 1 less
73588857acaSLaurent Vivier | than the desired result exponent whenever `zSig' is a complete, normalized
73688857acaSLaurent Vivier | significand.
73788857acaSLaurent Vivier *----------------------------------------------------------------------------*/
73888857acaSLaurent Vivier 
packFloat32(bool zSign,int zExp,uint32_t zSig)739c120391cSRichard Henderson static inline float32 packFloat32(bool zSign, int zExp, uint32_t zSig)
74088857acaSLaurent Vivier {
74188857acaSLaurent Vivier     return make_float32(
74288857acaSLaurent Vivier           (((uint32_t)zSign) << 31) + (((uint32_t)zExp) << 23) + zSig);
74388857acaSLaurent Vivier }
74488857acaSLaurent Vivier 
74588857acaSLaurent Vivier /*----------------------------------------------------------------------------
7466b4c305cSPaolo Bonzini | The pattern for a default generated single-precision NaN.
7476b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
748af39bc8cSAleksandar Markovic float32 float32_default_nan(float_status *status);
7496b4c305cSPaolo Bonzini 
7506b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
7516b4c305cSPaolo Bonzini | Software IEC/IEEE double-precision conversion routines.
7526b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
7532f6c74beSRichard Henderson 
7543dede407SRichard Henderson int16_t float64_to_int16_scalbn(float64, FloatRoundMode, int, float_status *);
7553dede407SRichard Henderson int32_t float64_to_int32_scalbn(float64, FloatRoundMode, int, float_status *);
7563dede407SRichard Henderson int64_t float64_to_int64_scalbn(float64, FloatRoundMode, int, float_status *);
7572f6c74beSRichard Henderson 
7580bb721d7SPeter Maydell int16_t float64_to_int16(float64, float_status *status);
759f4014512SPeter Maydell int32_t float64_to_int32(float64, float_status *status);
760f42c2224SPeter Maydell int64_t float64_to_int64(float64, float_status *status);
7612f6c74beSRichard Henderson 
7622f6c74beSRichard Henderson int16_t float64_to_int16_round_to_zero(float64, float_status *status);
7632f6c74beSRichard Henderson int32_t float64_to_int32_round_to_zero(float64, float_status *status);
764f42c2224SPeter Maydell int64_t float64_to_int64_round_to_zero(float64, float_status *status);
7652f6c74beSRichard Henderson 
766e2041f4dSRichard Henderson int32_t float64_to_int32_modulo(float64, FloatRoundMode, float_status *status);
767e2041f4dSRichard Henderson int64_t float64_to_int64_modulo(float64, FloatRoundMode, float_status *status);
768e2041f4dSRichard Henderson 
7693dede407SRichard Henderson uint16_t float64_to_uint16_scalbn(float64, FloatRoundMode, int, float_status *);
7703dede407SRichard Henderson uint32_t float64_to_uint32_scalbn(float64, FloatRoundMode, int, float_status *);
7713dede407SRichard Henderson uint64_t float64_to_uint64_scalbn(float64, FloatRoundMode, int, float_status *);
7722f6c74beSRichard Henderson 
7732f6c74beSRichard Henderson uint16_t float64_to_uint16(float64, float_status *status);
7742f6c74beSRichard Henderson uint32_t float64_to_uint32(float64, float_status *status);
7752f6c74beSRichard Henderson uint64_t float64_to_uint64(float64, float_status *status);
7762f6c74beSRichard Henderson 
7772f6c74beSRichard Henderson uint16_t float64_to_uint16_round_to_zero(float64, float_status *status);
7782f6c74beSRichard Henderson uint32_t float64_to_uint32_round_to_zero(float64, float_status *status);
7792f6c74beSRichard Henderson uint64_t float64_to_uint64_round_to_zero(float64, float_status *status);
7802f6c74beSRichard Henderson 
781e5a41ffaSPeter Maydell float32 float64_to_float32(float64, float_status *status);
782e5a41ffaSPeter Maydell floatx80 float64_to_floatx80(float64, float_status *status);
783e5a41ffaSPeter Maydell float128 float64_to_float128(float64, float_status *status);
7846b4c305cSPaolo Bonzini 
7856b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
7866b4c305cSPaolo Bonzini | Software IEC/IEEE double-precision operations.
7876b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
788e5a41ffaSPeter Maydell float64 float64_round_to_int(float64, float_status *status);
789e5a41ffaSPeter Maydell float64 float64_add(float64, float64, float_status *status);
790e5a41ffaSPeter Maydell float64 float64_sub(float64, float64, float_status *status);
791e5a41ffaSPeter Maydell float64 float64_mul(float64, float64, float_status *status);
792e5a41ffaSPeter Maydell float64 float64_div(float64, float64, float_status *status);
793e5a41ffaSPeter Maydell float64 float64_rem(float64, float64, float_status *status);
794e5a41ffaSPeter Maydell float64 float64_muladd(float64, float64, float64, int, float_status *status);
795e5a41ffaSPeter Maydell float64 float64_sqrt(float64, float_status *status);
796e5a41ffaSPeter Maydell float64 float64_log2(float64, float_status *status);
79771bfd65cSRichard Henderson FloatRelation float64_compare(float64, float64, float_status *status);
79871bfd65cSRichard Henderson FloatRelation float64_compare_quiet(float64, float64, float_status *status);
799e5a41ffaSPeter Maydell float64 float64_min(float64, float64, float_status *status);
800e5a41ffaSPeter Maydell float64 float64_max(float64, float64, float_status *status);
801e5a41ffaSPeter Maydell float64 float64_minnum(float64, float64, float_status *status);
802e5a41ffaSPeter Maydell float64 float64_maxnum(float64, float64, float_status *status);
803e5a41ffaSPeter Maydell float64 float64_minnummag(float64, float64, float_status *status);
804e5a41ffaSPeter Maydell float64 float64_maxnummag(float64, float64, float_status *status);
8050e903037SChih-Min Chao float64 float64_minimum_number(float64, float64, float_status *status);
8060e903037SChih-Min Chao float64 float64_maximum_number(float64, float64, float_status *status);
807150c7a91SRichard Henderson bool float64_is_quiet_nan(float64 a, float_status *status);
808150c7a91SRichard Henderson bool float64_is_signaling_nan(float64, float_status *status);
809d619bb98SRichard Henderson float64 float64_silence_nan(float64, float_status *status);
810e5a41ffaSPeter Maydell float64 float64_scalbn(float64, int, float_status *status);
8116b4c305cSPaolo Bonzini 
float64_abs(float64 a)812a49db98dSLuiz Capitulino static inline float64 float64_abs(float64 a)
8136b4c305cSPaolo Bonzini {
8146b4c305cSPaolo Bonzini     /* Note that abs does *not* handle NaN specially, nor does
8156b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
8166b4c305cSPaolo Bonzini      */
8176b4c305cSPaolo Bonzini     return make_float64(float64_val(a) & 0x7fffffffffffffffLL);
8186b4c305cSPaolo Bonzini }
8196b4c305cSPaolo Bonzini 
float64_chs(float64 a)820a49db98dSLuiz Capitulino static inline float64 float64_chs(float64 a)
8216b4c305cSPaolo Bonzini {
8226b4c305cSPaolo Bonzini     /* Note that chs does *not* handle NaN specially, nor does
8236b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
8246b4c305cSPaolo Bonzini      */
8256b4c305cSPaolo Bonzini     return make_float64(float64_val(a) ^ 0x8000000000000000LL);
8266b4c305cSPaolo Bonzini }
8276b4c305cSPaolo Bonzini 
float64_is_infinity(float64 a)828150c7a91SRichard Henderson static inline bool float64_is_infinity(float64 a)
8296b4c305cSPaolo Bonzini {
8306b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL;
8316b4c305cSPaolo Bonzini }
8326b4c305cSPaolo Bonzini 
float64_is_neg(float64 a)833150c7a91SRichard Henderson static inline bool float64_is_neg(float64 a)
8346b4c305cSPaolo Bonzini {
8356b4c305cSPaolo Bonzini     return float64_val(a) >> 63;
8366b4c305cSPaolo Bonzini }
8376b4c305cSPaolo Bonzini 
float64_is_zero(float64 a)838150c7a91SRichard Henderson static inline bool float64_is_zero(float64 a)
8396b4c305cSPaolo Bonzini {
8406b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7fffffffffffffffLL) == 0;
8416b4c305cSPaolo Bonzini }
8426b4c305cSPaolo Bonzini 
float64_is_any_nan(float64 a)843150c7a91SRichard Henderson static inline bool float64_is_any_nan(float64 a)
8446b4c305cSPaolo Bonzini {
8456b4c305cSPaolo Bonzini     return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL);
8466b4c305cSPaolo Bonzini }
8476b4c305cSPaolo Bonzini 
float64_is_zero_or_denormal(float64 a)848150c7a91SRichard Henderson static inline bool float64_is_zero_or_denormal(float64 a)
8496b4c305cSPaolo Bonzini {
8506b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7ff0000000000000LL) == 0;
8516b4c305cSPaolo Bonzini }
8526b4c305cSPaolo Bonzini 
float64_is_normal(float64 a)853588e6dfdSEmilio G. Cota static inline bool float64_is_normal(float64 a)
854588e6dfdSEmilio G. Cota {
85547393181SDavid Hildenbrand     return (((float64_val(a) >> 52) + 1) & 0x7ff) >= 2;
856588e6dfdSEmilio G. Cota }
857588e6dfdSEmilio G. Cota 
float64_is_denormal(float64 a)858588e6dfdSEmilio G. Cota static inline bool float64_is_denormal(float64 a)
859588e6dfdSEmilio G. Cota {
860588e6dfdSEmilio G. Cota     return float64_is_zero_or_denormal(a) && !float64_is_zero(a);
861588e6dfdSEmilio G. Cota }
862588e6dfdSEmilio G. Cota 
float64_is_zero_or_normal(float64 a)863315df0d1SEmilio G. Cota static inline bool float64_is_zero_or_normal(float64 a)
864315df0d1SEmilio G. Cota {
865315df0d1SEmilio G. Cota     return float64_is_normal(a) || float64_is_zero(a);
866315df0d1SEmilio G. Cota }
867315df0d1SEmilio G. Cota 
float64_set_sign(float64 a,int sign)868a49db98dSLuiz Capitulino static inline float64 float64_set_sign(float64 a, int sign)
8696b4c305cSPaolo Bonzini {
8706b4c305cSPaolo Bonzini     return make_float64((float64_val(a) & 0x7fffffffffffffffULL)
8716b4c305cSPaolo Bonzini                         | ((int64_t)sign << 63));
8726b4c305cSPaolo Bonzini }
8736b4c305cSPaolo Bonzini 
float64_eq(float64 a,float64 b,float_status * s)8740673ecdfSRichard Henderson static inline bool float64_eq(float64 a, float64 b, float_status *s)
8750673ecdfSRichard Henderson {
8760673ecdfSRichard Henderson     return float64_compare(a, b, s) == float_relation_equal;
8770673ecdfSRichard Henderson }
8780673ecdfSRichard Henderson 
float64_le(float64 a,float64 b,float_status * s)8790673ecdfSRichard Henderson static inline bool float64_le(float64 a, float64 b, float_status *s)
8800673ecdfSRichard Henderson {
8810673ecdfSRichard Henderson     return float64_compare(a, b, s) <= float_relation_equal;
8820673ecdfSRichard Henderson }
8830673ecdfSRichard Henderson 
float64_lt(float64 a,float64 b,float_status * s)8840673ecdfSRichard Henderson static inline bool float64_lt(float64 a, float64 b, float_status *s)
8850673ecdfSRichard Henderson {
8860673ecdfSRichard Henderson     return float64_compare(a, b, s) < float_relation_equal;
8870673ecdfSRichard Henderson }
8880673ecdfSRichard Henderson 
float64_unordered(float64 a,float64 b,float_status * s)8890673ecdfSRichard Henderson static inline bool float64_unordered(float64 a, float64 b, float_status *s)
8900673ecdfSRichard Henderson {
8910673ecdfSRichard Henderson     return float64_compare(a, b, s) == float_relation_unordered;
8920673ecdfSRichard Henderson }
8930673ecdfSRichard Henderson 
float64_eq_quiet(float64 a,float64 b,float_status * s)8940673ecdfSRichard Henderson static inline bool float64_eq_quiet(float64 a, float64 b, float_status *s)
8950673ecdfSRichard Henderson {
8960673ecdfSRichard Henderson     return float64_compare_quiet(a, b, s) == float_relation_equal;
8970673ecdfSRichard Henderson }
8980673ecdfSRichard Henderson 
float64_le_quiet(float64 a,float64 b,float_status * s)8990673ecdfSRichard Henderson static inline bool float64_le_quiet(float64 a, float64 b, float_status *s)
9000673ecdfSRichard Henderson {
9010673ecdfSRichard Henderson     return float64_compare_quiet(a, b, s) <= float_relation_equal;
9020673ecdfSRichard Henderson }
9030673ecdfSRichard Henderson 
float64_lt_quiet(float64 a,float64 b,float_status * s)9040673ecdfSRichard Henderson static inline bool float64_lt_quiet(float64 a, float64 b, float_status *s)
9050673ecdfSRichard Henderson {
9060673ecdfSRichard Henderson     return float64_compare_quiet(a, b, s) < float_relation_equal;
9070673ecdfSRichard Henderson }
9080673ecdfSRichard Henderson 
float64_unordered_quiet(float64 a,float64 b,float_status * s)9090673ecdfSRichard Henderson static inline bool float64_unordered_quiet(float64 a, float64 b,
9100673ecdfSRichard Henderson                                            float_status *s)
9110673ecdfSRichard Henderson {
9120673ecdfSRichard Henderson     return float64_compare_quiet(a, b, s) == float_relation_unordered;
9130673ecdfSRichard Henderson }
9140673ecdfSRichard Henderson 
9156b4c305cSPaolo Bonzini #define float64_zero make_float64(0)
9166b4c305cSPaolo Bonzini #define float64_half make_float64(0x3fe0000000000000LL)
917026e2d6eSAlex Bennée #define float64_one make_float64(0x3ff0000000000000LL)
918026e2d6eSAlex Bennée #define float64_one_point_five make_float64(0x3FF8000000000000ULL)
919026e2d6eSAlex Bennée #define float64_two make_float64(0x4000000000000000ULL)
920026e2d6eSAlex Bennée #define float64_three make_float64(0x4008000000000000ULL)
921026e2d6eSAlex Bennée #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
9226b4c305cSPaolo Bonzini #define float64_infinity make_float64(0x7ff0000000000000LL)
9236b4c305cSPaolo Bonzini 
9246b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
9256b4c305cSPaolo Bonzini | The pattern for a default generated double-precision NaN.
9266b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
927af39bc8cSAleksandar Markovic float64 float64_default_nan(float_status *status);
9286b4c305cSPaolo Bonzini 
9296b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
93042636fb9SRichard Henderson | Software IEC/IEEE double-precision operations, rounding to single precision,
93142636fb9SRichard Henderson | returning a result in double precision, with only one rounding step.
93242636fb9SRichard Henderson *----------------------------------------------------------------------------*/
93342636fb9SRichard Henderson 
93442636fb9SRichard Henderson float64 float64r32_add(float64, float64, float_status *status);
93542636fb9SRichard Henderson float64 float64r32_sub(float64, float64, float_status *status);
93642636fb9SRichard Henderson float64 float64r32_mul(float64, float64, float_status *status);
93742636fb9SRichard Henderson float64 float64r32_div(float64, float64, float_status *status);
93842636fb9SRichard Henderson float64 float64r32_muladd(float64, float64, float64, int, float_status *status);
93942636fb9SRichard Henderson float64 float64r32_sqrt(float64, float_status *status);
94042636fb9SRichard Henderson 
94142636fb9SRichard Henderson /*----------------------------------------------------------------------------
9426b4c305cSPaolo Bonzini | Software IEC/IEEE extended double-precision conversion routines.
9436b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
944f4014512SPeter Maydell int32_t floatx80_to_int32(floatx80, float_status *status);
945f4014512SPeter Maydell int32_t floatx80_to_int32_round_to_zero(floatx80, float_status *status);
946f42c2224SPeter Maydell int64_t floatx80_to_int64(floatx80, float_status *status);
947f42c2224SPeter Maydell int64_t floatx80_to_int64_round_to_zero(floatx80, float_status *status);
948e5a41ffaSPeter Maydell float32 floatx80_to_float32(floatx80, float_status *status);
949e5a41ffaSPeter Maydell float64 floatx80_to_float64(floatx80, float_status *status);
950e5a41ffaSPeter Maydell float128 floatx80_to_float128(floatx80, float_status *status);
9516b4c305cSPaolo Bonzini 
9526b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
9530f605c88SLaurent Vivier | The pattern for an extended double-precision inf.
9540f605c88SLaurent Vivier *----------------------------------------------------------------------------*/
9550f605c88SLaurent Vivier extern const floatx80 floatx80_infinity;
9560f605c88SLaurent Vivier 
9570f605c88SLaurent Vivier /*----------------------------------------------------------------------------
9586b4c305cSPaolo Bonzini | Software IEC/IEEE extended double-precision operations.
9596b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
9600f721292SLaurent Vivier floatx80 floatx80_round(floatx80 a, float_status *status);
961e5a41ffaSPeter Maydell floatx80 floatx80_round_to_int(floatx80, float_status *status);
962e5a41ffaSPeter Maydell floatx80 floatx80_add(floatx80, floatx80, float_status *status);
963e5a41ffaSPeter Maydell floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
964e5a41ffaSPeter Maydell floatx80 floatx80_mul(floatx80, floatx80, float_status *status);
965e5a41ffaSPeter Maydell floatx80 floatx80_div(floatx80, floatx80, float_status *status);
966445810ecSJoseph Myers floatx80 floatx80_modrem(floatx80, floatx80, bool, uint64_t *,
967445810ecSJoseph Myers                          float_status *status);
9686b8b0136SJoseph Myers floatx80 floatx80_mod(floatx80, floatx80, float_status *status);
969e5a41ffaSPeter Maydell floatx80 floatx80_rem(floatx80, floatx80, float_status *status);
970e5a41ffaSPeter Maydell floatx80 floatx80_sqrt(floatx80, float_status *status);
97171bfd65cSRichard Henderson FloatRelation floatx80_compare(floatx80, floatx80, float_status *status);
97271bfd65cSRichard Henderson FloatRelation floatx80_compare_quiet(floatx80, floatx80, float_status *status);
973af39bc8cSAleksandar Markovic int floatx80_is_quiet_nan(floatx80, float_status *status);
974af39bc8cSAleksandar Markovic int floatx80_is_signaling_nan(floatx80, float_status *status);
975d619bb98SRichard Henderson floatx80 floatx80_silence_nan(floatx80, float_status *status);
976e5a41ffaSPeter Maydell floatx80 floatx80_scalbn(floatx80, int, float_status *status);
9776b4c305cSPaolo Bonzini 
floatx80_abs(floatx80 a)978a49db98dSLuiz Capitulino static inline floatx80 floatx80_abs(floatx80 a)
9796b4c305cSPaolo Bonzini {
9806b4c305cSPaolo Bonzini     a.high &= 0x7fff;
9816b4c305cSPaolo Bonzini     return a;
9826b4c305cSPaolo Bonzini }
9836b4c305cSPaolo Bonzini 
floatx80_chs(floatx80 a)984a49db98dSLuiz Capitulino static inline floatx80 floatx80_chs(floatx80 a)
9856b4c305cSPaolo Bonzini {
9866b4c305cSPaolo Bonzini     a.high ^= 0x8000;
9876b4c305cSPaolo Bonzini     return a;
9886b4c305cSPaolo Bonzini }
9896b4c305cSPaolo Bonzini 
floatx80_is_infinity(floatx80 a)990150c7a91SRichard Henderson static inline bool floatx80_is_infinity(floatx80 a)
9916b4c305cSPaolo Bonzini {
9920f605c88SLaurent Vivier #if defined(TARGET_M68K)
9930f605c88SLaurent Vivier     return (a.high & 0x7fff) == floatx80_infinity.high && !(a.low << 1);
9940f605c88SLaurent Vivier #else
9950f605c88SLaurent Vivier     return (a.high & 0x7fff) == floatx80_infinity.high &&
9960f605c88SLaurent Vivier                        a.low == floatx80_infinity.low;
9970f605c88SLaurent Vivier #endif
9986b4c305cSPaolo Bonzini }
9996b4c305cSPaolo Bonzini 
floatx80_is_neg(floatx80 a)1000150c7a91SRichard Henderson static inline bool floatx80_is_neg(floatx80 a)
10016b4c305cSPaolo Bonzini {
10026b4c305cSPaolo Bonzini     return a.high >> 15;
10036b4c305cSPaolo Bonzini }
10046b4c305cSPaolo Bonzini 
floatx80_is_zero(floatx80 a)1005150c7a91SRichard Henderson static inline bool floatx80_is_zero(floatx80 a)
10066b4c305cSPaolo Bonzini {
10076b4c305cSPaolo Bonzini     return (a.high & 0x7fff) == 0 && a.low == 0;
10086b4c305cSPaolo Bonzini }
10096b4c305cSPaolo Bonzini 
floatx80_is_zero_or_denormal(floatx80 a)1010150c7a91SRichard Henderson static inline bool floatx80_is_zero_or_denormal(floatx80 a)
10116b4c305cSPaolo Bonzini {
10126b4c305cSPaolo Bonzini     return (a.high & 0x7fff) == 0;
10136b4c305cSPaolo Bonzini }
10146b4c305cSPaolo Bonzini 
floatx80_is_any_nan(floatx80 a)1015150c7a91SRichard Henderson static inline bool floatx80_is_any_nan(floatx80 a)
10166b4c305cSPaolo Bonzini {
10176b4c305cSPaolo Bonzini     return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
10186b4c305cSPaolo Bonzini }
10196b4c305cSPaolo Bonzini 
floatx80_eq(floatx80 a,floatx80 b,float_status * s)1020c6baf650SRichard Henderson static inline bool floatx80_eq(floatx80 a, floatx80 b, float_status *s)
1021c6baf650SRichard Henderson {
1022c6baf650SRichard Henderson     return floatx80_compare(a, b, s) == float_relation_equal;
1023c6baf650SRichard Henderson }
1024c6baf650SRichard Henderson 
floatx80_le(floatx80 a,floatx80 b,float_status * s)1025c6baf650SRichard Henderson static inline bool floatx80_le(floatx80 a, floatx80 b, float_status *s)
1026c6baf650SRichard Henderson {
1027c6baf650SRichard Henderson     return floatx80_compare(a, b, s) <= float_relation_equal;
1028c6baf650SRichard Henderson }
1029c6baf650SRichard Henderson 
floatx80_lt(floatx80 a,floatx80 b,float_status * s)1030c6baf650SRichard Henderson static inline bool floatx80_lt(floatx80 a, floatx80 b, float_status *s)
1031c6baf650SRichard Henderson {
1032c6baf650SRichard Henderson     return floatx80_compare(a, b, s) < float_relation_equal;
1033c6baf650SRichard Henderson }
1034c6baf650SRichard Henderson 
floatx80_unordered(floatx80 a,floatx80 b,float_status * s)1035c6baf650SRichard Henderson static inline bool floatx80_unordered(floatx80 a, floatx80 b, float_status *s)
1036c6baf650SRichard Henderson {
1037c6baf650SRichard Henderson     return floatx80_compare(a, b, s) == float_relation_unordered;
1038c6baf650SRichard Henderson }
1039c6baf650SRichard Henderson 
floatx80_eq_quiet(floatx80 a,floatx80 b,float_status * s)1040c6baf650SRichard Henderson static inline bool floatx80_eq_quiet(floatx80 a, floatx80 b, float_status *s)
1041c6baf650SRichard Henderson {
1042c6baf650SRichard Henderson     return floatx80_compare_quiet(a, b, s) == float_relation_equal;
1043c6baf650SRichard Henderson }
1044c6baf650SRichard Henderson 
floatx80_le_quiet(floatx80 a,floatx80 b,float_status * s)1045c6baf650SRichard Henderson static inline bool floatx80_le_quiet(floatx80 a, floatx80 b, float_status *s)
1046c6baf650SRichard Henderson {
1047c6baf650SRichard Henderson     return floatx80_compare_quiet(a, b, s) <= float_relation_equal;
1048c6baf650SRichard Henderson }
1049c6baf650SRichard Henderson 
floatx80_lt_quiet(floatx80 a,floatx80 b,float_status * s)1050c6baf650SRichard Henderson static inline bool floatx80_lt_quiet(floatx80 a, floatx80 b, float_status *s)
1051c6baf650SRichard Henderson {
1052c6baf650SRichard Henderson     return floatx80_compare_quiet(a, b, s) < float_relation_equal;
1053c6baf650SRichard Henderson }
1054c6baf650SRichard Henderson 
floatx80_unordered_quiet(floatx80 a,floatx80 b,float_status * s)1055c6baf650SRichard Henderson static inline bool floatx80_unordered_quiet(floatx80 a, floatx80 b,
1056c6baf650SRichard Henderson                                            float_status *s)
1057c6baf650SRichard Henderson {
1058c6baf650SRichard Henderson     return floatx80_compare_quiet(a, b, s) == float_relation_unordered;
1059c6baf650SRichard Henderson }
1060c6baf650SRichard Henderson 
1061d1eb8f2aSAndrew Dutcher /*----------------------------------------------------------------------------
1062d1eb8f2aSAndrew Dutcher | Return whether the given value is an invalid floatx80 encoding.
1063d1eb8f2aSAndrew Dutcher | Invalid floatx80 encodings arise when the integer bit is not set, but
1064d1eb8f2aSAndrew Dutcher | the exponent is not zero. The only times the integer bit is permitted to
1065d1eb8f2aSAndrew Dutcher | be zero is in subnormal numbers and the value zero.
1066d1eb8f2aSAndrew Dutcher | This includes what the Intel software developer's manual calls pseudo-NaNs,
1067d1eb8f2aSAndrew Dutcher | pseudo-infinities and un-normal numbers. It does not include
1068d1eb8f2aSAndrew Dutcher | pseudo-denormals, which must still be correctly handled as inputs even
1069d1eb8f2aSAndrew Dutcher | if they are never generated as outputs.
1070d1eb8f2aSAndrew Dutcher *----------------------------------------------------------------------------*/
floatx80_invalid_encoding(floatx80 a)1071d1eb8f2aSAndrew Dutcher static inline bool floatx80_invalid_encoding(floatx80 a)
1072d1eb8f2aSAndrew Dutcher {
1073d159dd05SLaurent Vivier #if defined(TARGET_M68K)
1074d159dd05SLaurent Vivier     /*-------------------------------------------------------------------------
1075d159dd05SLaurent Vivier     | With m68k, the explicit integer bit can be zero in the case of:
1076d159dd05SLaurent Vivier     | - zeros                (exp == 0, mantissa == 0)
1077d159dd05SLaurent Vivier     | - denormalized numbers (exp == 0, mantissa != 0)
1078d159dd05SLaurent Vivier     | - unnormalized numbers (exp != 0, exp < 0x7FFF)
1079d159dd05SLaurent Vivier     | - infinities           (exp == 0x7FFF, mantissa == 0)
1080d159dd05SLaurent Vivier     | - not-a-numbers        (exp == 0x7FFF, mantissa != 0)
1081d159dd05SLaurent Vivier     |
1082d159dd05SLaurent Vivier     | For infinities and NaNs, the explicit integer bit can be either one or
1083d159dd05SLaurent Vivier     | zero.
1084d159dd05SLaurent Vivier     |
1085d159dd05SLaurent Vivier     | The IEEE 754 standard does not define a zero integer bit. Such a number
1086d159dd05SLaurent Vivier     | is an unnormalized number. Hardware does not directly support
1087d159dd05SLaurent Vivier     | denormalized and unnormalized numbers, but implicitly supports them by
1088d159dd05SLaurent Vivier     | trapping them as unimplemented data types, allowing efficient conversion
1089d159dd05SLaurent Vivier     | in software.
1090d159dd05SLaurent Vivier     |
1091d159dd05SLaurent Vivier     | See "M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL",
1092d159dd05SLaurent Vivier     |     "1.6 FLOATING-POINT DATA TYPES"
1093d159dd05SLaurent Vivier     *------------------------------------------------------------------------*/
1094d159dd05SLaurent Vivier     return false;
1095d159dd05SLaurent Vivier #else
1096d1eb8f2aSAndrew Dutcher     return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0;
1097d159dd05SLaurent Vivier #endif
1098d1eb8f2aSAndrew Dutcher }
1099d1eb8f2aSAndrew Dutcher 
11006b4c305cSPaolo Bonzini #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
1101163b3d1aSLaszlo Ersek #define floatx80_zero_init make_floatx80_init(0x0000, 0x0000000000000000LL)
11026b4c305cSPaolo Bonzini #define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
11036b4c305cSPaolo Bonzini #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
11046b4c305cSPaolo Bonzini #define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
11056b4c305cSPaolo Bonzini #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
11066b4c305cSPaolo Bonzini 
11076b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
110888857acaSLaurent Vivier | Returns the fraction bits of the extended double-precision floating-point
110988857acaSLaurent Vivier | value `a'.
111088857acaSLaurent Vivier *----------------------------------------------------------------------------*/
111188857acaSLaurent Vivier 
extractFloatx80Frac(floatx80 a)111288857acaSLaurent Vivier static inline uint64_t extractFloatx80Frac(floatx80 a)
111388857acaSLaurent Vivier {
111488857acaSLaurent Vivier     return a.low;
111588857acaSLaurent Vivier }
111688857acaSLaurent Vivier 
111788857acaSLaurent Vivier /*----------------------------------------------------------------------------
111888857acaSLaurent Vivier | Returns the exponent bits of the extended double-precision floating-point
111988857acaSLaurent Vivier | value `a'.
112088857acaSLaurent Vivier *----------------------------------------------------------------------------*/
112188857acaSLaurent Vivier 
extractFloatx80Exp(floatx80 a)112288857acaSLaurent Vivier static inline int32_t extractFloatx80Exp(floatx80 a)
112388857acaSLaurent Vivier {
112488857acaSLaurent Vivier     return a.high & 0x7FFF;
112588857acaSLaurent Vivier }
112688857acaSLaurent Vivier 
112788857acaSLaurent Vivier /*----------------------------------------------------------------------------
112888857acaSLaurent Vivier | Returns the sign bit of the extended double-precision floating-point value
112988857acaSLaurent Vivier | `a'.
113088857acaSLaurent Vivier *----------------------------------------------------------------------------*/
113188857acaSLaurent Vivier 
extractFloatx80Sign(floatx80 a)1132c120391cSRichard Henderson static inline bool extractFloatx80Sign(floatx80 a)
113388857acaSLaurent Vivier {
113488857acaSLaurent Vivier     return a.high >> 15;
113588857acaSLaurent Vivier }
113688857acaSLaurent Vivier 
113788857acaSLaurent Vivier /*----------------------------------------------------------------------------
113888857acaSLaurent Vivier | Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
113988857acaSLaurent Vivier | extended double-precision floating-point value, returning the result.
114088857acaSLaurent Vivier *----------------------------------------------------------------------------*/
114188857acaSLaurent Vivier 
packFloatx80(bool zSign,int32_t zExp,uint64_t zSig)1142c120391cSRichard Henderson static inline floatx80 packFloatx80(bool zSign, int32_t zExp, uint64_t zSig)
114388857acaSLaurent Vivier {
114488857acaSLaurent Vivier     floatx80 z;
114588857acaSLaurent Vivier 
114688857acaSLaurent Vivier     z.low = zSig;
114788857acaSLaurent Vivier     z.high = (((uint16_t)zSign) << 15) + zExp;
114888857acaSLaurent Vivier     return z;
114988857acaSLaurent Vivier }
115088857acaSLaurent Vivier 
115188857acaSLaurent Vivier /*----------------------------------------------------------------------------
115288857acaSLaurent Vivier | Normalizes the subnormal extended double-precision floating-point value
115388857acaSLaurent Vivier | represented by the denormalized significand `aSig'.  The normalized exponent
115488857acaSLaurent Vivier | and significand are stored at the locations pointed to by `zExpPtr' and
115588857acaSLaurent Vivier | `zSigPtr', respectively.
115688857acaSLaurent Vivier *----------------------------------------------------------------------------*/
115788857acaSLaurent Vivier 
115888857acaSLaurent Vivier void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
115988857acaSLaurent Vivier                                 uint64_t *zSigPtr);
116088857acaSLaurent Vivier 
116188857acaSLaurent Vivier /*----------------------------------------------------------------------------
116288857acaSLaurent Vivier | Takes two extended double-precision floating-point values `a' and `b', one
116388857acaSLaurent Vivier | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
116488857acaSLaurent Vivier | `b' is a signaling NaN, the invalid exception is raised.
116588857acaSLaurent Vivier *----------------------------------------------------------------------------*/
116688857acaSLaurent Vivier 
116788857acaSLaurent Vivier floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status);
116888857acaSLaurent Vivier 
116988857acaSLaurent Vivier /*----------------------------------------------------------------------------
117088857acaSLaurent Vivier | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
117188857acaSLaurent Vivier | and extended significand formed by the concatenation of `zSig0' and `zSig1',
117288857acaSLaurent Vivier | and returns the proper extended double-precision floating-point value
117388857acaSLaurent Vivier | corresponding to the abstract input.  Ordinarily, the abstract value is
117488857acaSLaurent Vivier | rounded and packed into the extended double-precision format, with the
117588857acaSLaurent Vivier | inexact exception raised if the abstract input cannot be represented
117688857acaSLaurent Vivier | exactly.  However, if the abstract value is too large, the overflow and
117788857acaSLaurent Vivier | inexact exceptions are raised and an infinity or maximal finite value is
117888857acaSLaurent Vivier | returned.  If the abstract value is too small, the input value is rounded to
117988857acaSLaurent Vivier | a subnormal number, and the underflow and inexact exceptions are raised if
118088857acaSLaurent Vivier | the abstract input cannot be represented exactly as a subnormal extended
118188857acaSLaurent Vivier | double-precision floating-point number.
118288857acaSLaurent Vivier |     If `roundingPrecision' is 32 or 64, the result is rounded to the same
118388857acaSLaurent Vivier | number of bits as single or double precision, respectively.  Otherwise, the
118488857acaSLaurent Vivier | result is rounded to the full precision of the extended double-precision
118588857acaSLaurent Vivier | format.
118688857acaSLaurent Vivier |     The input significand must be normalized or smaller.  If the input
118788857acaSLaurent Vivier | significand is not normalized, `zExp' must be 0; in that case, the result
118888857acaSLaurent Vivier | returned is a subnormal number, and it must not require rounding.  The
118988857acaSLaurent Vivier | handling of underflow and overflow follows the IEC/IEEE Standard for Binary
119088857acaSLaurent Vivier | Floating-Point Arithmetic.
119188857acaSLaurent Vivier *----------------------------------------------------------------------------*/
119288857acaSLaurent Vivier 
11938da5f1dbSRichard Henderson floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign,
119488857acaSLaurent Vivier                               int32_t zExp, uint64_t zSig0, uint64_t zSig1,
119588857acaSLaurent Vivier                               float_status *status);
119688857acaSLaurent Vivier 
119788857acaSLaurent Vivier /*----------------------------------------------------------------------------
119888857acaSLaurent Vivier | Takes an abstract floating-point value having sign `zSign', exponent
119988857acaSLaurent Vivier | `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
120088857acaSLaurent Vivier | and returns the proper extended double-precision floating-point value
120188857acaSLaurent Vivier | corresponding to the abstract input.  This routine is just like
120288857acaSLaurent Vivier | `roundAndPackFloatx80' except that the input significand does not have to be
120388857acaSLaurent Vivier | normalized.
120488857acaSLaurent Vivier *----------------------------------------------------------------------------*/
120588857acaSLaurent Vivier 
12068da5f1dbSRichard Henderson floatx80 normalizeRoundAndPackFloatx80(FloatX80RoundPrec roundingPrecision,
1207c120391cSRichard Henderson                                        bool zSign, int32_t zExp,
120888857acaSLaurent Vivier                                        uint64_t zSig0, uint64_t zSig1,
120988857acaSLaurent Vivier                                        float_status *status);
121088857acaSLaurent Vivier 
121188857acaSLaurent Vivier /*----------------------------------------------------------------------------
12126b4c305cSPaolo Bonzini | The pattern for a default generated extended double-precision NaN.
12136b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1214af39bc8cSAleksandar Markovic floatx80 floatx80_default_nan(float_status *status);
12156b4c305cSPaolo Bonzini 
12166b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
12176b4c305cSPaolo Bonzini | Software IEC/IEEE quadruple-precision conversion routines.
12186b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1219f4014512SPeter Maydell int32_t float128_to_int32(float128, float_status *status);
1220f4014512SPeter Maydell int32_t float128_to_int32_round_to_zero(float128, float_status *status);
1221f42c2224SPeter Maydell int64_t float128_to_int64(float128, float_status *status);
1222bea59230SMatheus Ferst Int128 float128_to_int128(float128, float_status *status);
1223f42c2224SPeter Maydell int64_t float128_to_int64_round_to_zero(float128, float_status *status);
1224bea59230SMatheus Ferst Int128 float128_to_int128_round_to_zero(float128, float_status *status);
12252e6d8568SBharata B Rao uint64_t float128_to_uint64(float128, float_status *status);
12264de49ddfSMatheus Ferst Int128 float128_to_uint128(float128, float_status *status);
12272e6d8568SBharata B Rao uint64_t float128_to_uint64_round_to_zero(float128, float_status *status);
12284de49ddfSMatheus Ferst Int128 float128_to_uint128_round_to_zero(float128, float_status *status);
1229e45de992SDavid Hildenbrand uint32_t float128_to_uint32(float128, float_status *status);
1230fd425037SBharata B Rao uint32_t float128_to_uint32_round_to_zero(float128, float_status *status);
1231e5a41ffaSPeter Maydell float32 float128_to_float32(float128, float_status *status);
1232e5a41ffaSPeter Maydell float64 float128_to_float64(float128, float_status *status);
1233e5a41ffaSPeter Maydell floatx80 float128_to_floatx80(float128, float_status *status);
12346b4c305cSPaolo Bonzini 
12356b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
12366b4c305cSPaolo Bonzini | Software IEC/IEEE quadruple-precision operations.
12376b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1238e5a41ffaSPeter Maydell float128 float128_round_to_int(float128, float_status *status);
1239e5a41ffaSPeter Maydell float128 float128_add(float128, float128, float_status *status);
1240e5a41ffaSPeter Maydell float128 float128_sub(float128, float128, float_status *status);
1241e5a41ffaSPeter Maydell float128 float128_mul(float128, float128, float_status *status);
1242dedd123cSRichard Henderson float128 float128_muladd(float128, float128, float128, int,
1243dedd123cSRichard Henderson                          float_status *status);
1244e5a41ffaSPeter Maydell float128 float128_div(float128, float128, float_status *status);
1245e5a41ffaSPeter Maydell float128 float128_rem(float128, float128, float_status *status);
1246e5a41ffaSPeter Maydell float128 float128_sqrt(float128, float_status *status);
124771bfd65cSRichard Henderson FloatRelation float128_compare(float128, float128, float_status *status);
124871bfd65cSRichard Henderson FloatRelation float128_compare_quiet(float128, float128, float_status *status);
1249ceebc129SDavid Hildenbrand float128 float128_min(float128, float128, float_status *status);
1250ceebc129SDavid Hildenbrand float128 float128_max(float128, float128, float_status *status);
1251ceebc129SDavid Hildenbrand float128 float128_minnum(float128, float128, float_status *status);
1252ceebc129SDavid Hildenbrand float128 float128_maxnum(float128, float128, float_status *status);
1253ceebc129SDavid Hildenbrand float128 float128_minnummag(float128, float128, float_status *status);
1254ceebc129SDavid Hildenbrand float128 float128_maxnummag(float128, float128, float_status *status);
12550e903037SChih-Min Chao float128 float128_minimum_number(float128, float128, float_status *status);
12560e903037SChih-Min Chao float128 float128_maximum_number(float128, float128, float_status *status);
1257150c7a91SRichard Henderson bool float128_is_quiet_nan(float128, float_status *status);
1258150c7a91SRichard Henderson bool float128_is_signaling_nan(float128, float_status *status);
1259d619bb98SRichard Henderson float128 float128_silence_nan(float128, float_status *status);
1260e5a41ffaSPeter Maydell float128 float128_scalbn(float128, int, float_status *status);
12616b4c305cSPaolo Bonzini 
float128_abs(float128 a)1262a49db98dSLuiz Capitulino static inline float128 float128_abs(float128 a)
12636b4c305cSPaolo Bonzini {
12646b4c305cSPaolo Bonzini     a.high &= 0x7fffffffffffffffLL;
12656b4c305cSPaolo Bonzini     return a;
12666b4c305cSPaolo Bonzini }
12676b4c305cSPaolo Bonzini 
float128_chs(float128 a)1268a49db98dSLuiz Capitulino static inline float128 float128_chs(float128 a)
12696b4c305cSPaolo Bonzini {
12706b4c305cSPaolo Bonzini     a.high ^= 0x8000000000000000LL;
12716b4c305cSPaolo Bonzini     return a;
12726b4c305cSPaolo Bonzini }
12736b4c305cSPaolo Bonzini 
float128_is_infinity(float128 a)1274150c7a91SRichard Henderson static inline bool float128_is_infinity(float128 a)
12756b4c305cSPaolo Bonzini {
12766b4c305cSPaolo Bonzini     return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0;
12776b4c305cSPaolo Bonzini }
12786b4c305cSPaolo Bonzini 
float128_is_neg(float128 a)1279150c7a91SRichard Henderson static inline bool float128_is_neg(float128 a)
12806b4c305cSPaolo Bonzini {
12816b4c305cSPaolo Bonzini     return a.high >> 63;
12826b4c305cSPaolo Bonzini }
12836b4c305cSPaolo Bonzini 
float128_is_zero(float128 a)1284150c7a91SRichard Henderson static inline bool float128_is_zero(float128 a)
12856b4c305cSPaolo Bonzini {
12866b4c305cSPaolo Bonzini     return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
12876b4c305cSPaolo Bonzini }
12886b4c305cSPaolo Bonzini 
float128_is_zero_or_denormal(float128 a)1289150c7a91SRichard Henderson static inline bool float128_is_zero_or_denormal(float128 a)
12906b4c305cSPaolo Bonzini {
12916b4c305cSPaolo Bonzini     return (a.high & 0x7fff000000000000LL) == 0;
12926b4c305cSPaolo Bonzini }
12936b4c305cSPaolo Bonzini 
float128_is_normal(float128 a)129447393181SDavid Hildenbrand static inline bool float128_is_normal(float128 a)
129547393181SDavid Hildenbrand {
129647393181SDavid Hildenbrand     return (((a.high >> 48) + 1) & 0x7fff) >= 2;
129747393181SDavid Hildenbrand }
129847393181SDavid Hildenbrand 
float128_is_denormal(float128 a)129947393181SDavid Hildenbrand static inline bool float128_is_denormal(float128 a)
130047393181SDavid Hildenbrand {
130147393181SDavid Hildenbrand     return float128_is_zero_or_denormal(a) && !float128_is_zero(a);
130247393181SDavid Hildenbrand }
130347393181SDavid Hildenbrand 
float128_is_any_nan(float128 a)1304150c7a91SRichard Henderson static inline bool float128_is_any_nan(float128 a)
13056b4c305cSPaolo Bonzini {
13066b4c305cSPaolo Bonzini     return ((a.high >> 48) & 0x7fff) == 0x7fff &&
13076b4c305cSPaolo Bonzini         ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0));
13086b4c305cSPaolo Bonzini }
13096b4c305cSPaolo Bonzini 
float128_eq(float128 a,float128 b,float_status * s)1310b7b1ac68SRichard Henderson static inline bool float128_eq(float128 a, float128 b, float_status *s)
1311b7b1ac68SRichard Henderson {
1312b7b1ac68SRichard Henderson     return float128_compare(a, b, s) == float_relation_equal;
1313b7b1ac68SRichard Henderson }
1314b7b1ac68SRichard Henderson 
float128_le(float128 a,float128 b,float_status * s)1315b7b1ac68SRichard Henderson static inline bool float128_le(float128 a, float128 b, float_status *s)
1316b7b1ac68SRichard Henderson {
1317b7b1ac68SRichard Henderson     return float128_compare(a, b, s) <= float_relation_equal;
1318b7b1ac68SRichard Henderson }
1319b7b1ac68SRichard Henderson 
float128_lt(float128 a,float128 b,float_status * s)1320b7b1ac68SRichard Henderson static inline bool float128_lt(float128 a, float128 b, float_status *s)
1321b7b1ac68SRichard Henderson {
1322b7b1ac68SRichard Henderson     return float128_compare(a, b, s) < float_relation_equal;
1323b7b1ac68SRichard Henderson }
1324b7b1ac68SRichard Henderson 
float128_unordered(float128 a,float128 b,float_status * s)1325b7b1ac68SRichard Henderson static inline bool float128_unordered(float128 a, float128 b, float_status *s)
1326b7b1ac68SRichard Henderson {
1327b7b1ac68SRichard Henderson     return float128_compare(a, b, s) == float_relation_unordered;
1328b7b1ac68SRichard Henderson }
1329b7b1ac68SRichard Henderson 
float128_eq_quiet(float128 a,float128 b,float_status * s)1330b7b1ac68SRichard Henderson static inline bool float128_eq_quiet(float128 a, float128 b, float_status *s)
1331b7b1ac68SRichard Henderson {
1332b7b1ac68SRichard Henderson     return float128_compare_quiet(a, b, s) == float_relation_equal;
1333b7b1ac68SRichard Henderson }
1334b7b1ac68SRichard Henderson 
float128_le_quiet(float128 a,float128 b,float_status * s)1335b7b1ac68SRichard Henderson static inline bool float128_le_quiet(float128 a, float128 b, float_status *s)
1336b7b1ac68SRichard Henderson {
1337b7b1ac68SRichard Henderson     return float128_compare_quiet(a, b, s) <= float_relation_equal;
1338b7b1ac68SRichard Henderson }
1339b7b1ac68SRichard Henderson 
float128_lt_quiet(float128 a,float128 b,float_status * s)1340b7b1ac68SRichard Henderson static inline bool float128_lt_quiet(float128 a, float128 b, float_status *s)
1341b7b1ac68SRichard Henderson {
1342b7b1ac68SRichard Henderson     return float128_compare_quiet(a, b, s) < float_relation_equal;
1343b7b1ac68SRichard Henderson }
1344b7b1ac68SRichard Henderson 
float128_unordered_quiet(float128 a,float128 b,float_status * s)1345b7b1ac68SRichard Henderson static inline bool float128_unordered_quiet(float128 a, float128 b,
1346b7b1ac68SRichard Henderson                                            float_status *s)
1347b7b1ac68SRichard Henderson {
1348b7b1ac68SRichard Henderson     return float128_compare_quiet(a, b, s) == float_relation_unordered;
1349b7b1ac68SRichard Henderson }
1350b7b1ac68SRichard Henderson 
13511e397eadSRichard Henderson #define float128_zero make_float128(0, 0)
13521e397eadSRichard Henderson 
13536b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
13546b4c305cSPaolo Bonzini | The pattern for a default generated quadruple-precision NaN.
13556b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1356af39bc8cSAleksandar Markovic float128 float128_default_nan(float_status *status);
13576b4c305cSPaolo Bonzini 
1358175de524SMarkus Armbruster #endif /* SOFTFLOAT_H */
1359