xref: /qemu/include/fpu/softfloat.h (revision 0d93d8ec)
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"
986b4c305cSPaolo Bonzini 
996b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1006b4c305cSPaolo Bonzini | Routine to raise any or all of the software IEC/IEEE floating-point
1016b4c305cSPaolo Bonzini | exception flags.
1026b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
103dfd60767SPranith Kumar void float_raise(uint8_t flags, float_status *status);
1046b4c305cSPaolo Bonzini 
1056b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1067baeabceSAlex Bennée | If `a' is denormal and we are in flush-to-zero mode then set the
1077baeabceSAlex Bennée | input-denormal exception and return zero. Otherwise just return the value.
1087baeabceSAlex Bennée *----------------------------------------------------------------------------*/
109210cbd49SAlex Bennée float16 float16_squash_input_denormal(float16 a, float_status *status);
110e5a41ffaSPeter Maydell float32 float32_squash_input_denormal(float32 a, float_status *status);
111e5a41ffaSPeter Maydell float64 float64_squash_input_denormal(float64 a, float_status *status);
1127baeabceSAlex Bennée 
1137baeabceSAlex Bennée /*----------------------------------------------------------------------------
1146b4c305cSPaolo Bonzini | Options to indicate which negations to perform in float*_muladd()
1156b4c305cSPaolo Bonzini | Using these differs from negating an input or output before calling
1166b4c305cSPaolo Bonzini | the muladd function in that this means that a NaN doesn't have its
1176b4c305cSPaolo Bonzini | sign bit inverted before it is propagated.
11867d43538SPeter Maydell | We also support halving the result before rounding, as a special
11967d43538SPeter Maydell | case to support the ARM fused-sqrt-step instruction FRSQRTS.
1206b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1216b4c305cSPaolo Bonzini enum {
1226b4c305cSPaolo Bonzini     float_muladd_negate_c = 1,
1236b4c305cSPaolo Bonzini     float_muladd_negate_product = 2,
1246b4c305cSPaolo Bonzini     float_muladd_negate_result = 4,
12567d43538SPeter Maydell     float_muladd_halve_result = 8,
1266b4c305cSPaolo Bonzini };
1276b4c305cSPaolo Bonzini 
1286b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1296b4c305cSPaolo Bonzini | Software IEC/IEEE integer-to-floating-point conversion routines.
1306b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1312abdfe24SRichard Henderson 
1322abdfe24SRichard Henderson float16 int16_to_float16_scalbn(int16_t a, int, float_status *status);
1332abdfe24SRichard Henderson float16 int32_to_float16_scalbn(int32_t a, int, float_status *status);
1342abdfe24SRichard Henderson float16 int64_to_float16_scalbn(int64_t a, int, float_status *status);
1352abdfe24SRichard Henderson float16 uint16_to_float16_scalbn(uint16_t a, int, float_status *status);
1362abdfe24SRichard Henderson float16 uint32_to_float16_scalbn(uint32_t a, int, float_status *status);
1372abdfe24SRichard Henderson float16 uint64_to_float16_scalbn(uint64_t a, int, float_status *status);
1382abdfe24SRichard Henderson 
139*0d93d8ecSFrank Chang float16 int8_to_float16(int8_t a, float_status *status);
1402abdfe24SRichard Henderson float16 int16_to_float16(int16_t a, float_status *status);
1412abdfe24SRichard Henderson float16 int32_to_float16(int32_t a, float_status *status);
1422abdfe24SRichard Henderson float16 int64_to_float16(int64_t a, float_status *status);
143*0d93d8ecSFrank Chang float16 uint8_to_float16(uint8_t a, float_status *status);
1442abdfe24SRichard Henderson float16 uint16_to_float16(uint16_t a, float_status *status);
1452abdfe24SRichard Henderson float16 uint32_to_float16(uint32_t a, float_status *status);
1462abdfe24SRichard Henderson float16 uint64_to_float16(uint64_t a, float_status *status);
1472abdfe24SRichard Henderson 
1482abdfe24SRichard Henderson float32 int16_to_float32_scalbn(int16_t, int, float_status *status);
1492abdfe24SRichard Henderson float32 int32_to_float32_scalbn(int32_t, int, float_status *status);
1502abdfe24SRichard Henderson float32 int64_to_float32_scalbn(int64_t, int, float_status *status);
1512abdfe24SRichard Henderson float32 uint16_to_float32_scalbn(uint16_t, int, float_status *status);
1522abdfe24SRichard Henderson float32 uint32_to_float32_scalbn(uint32_t, int, float_status *status);
1532abdfe24SRichard Henderson float32 uint64_to_float32_scalbn(uint64_t, int, float_status *status);
1542abdfe24SRichard Henderson 
155c02e1fb8SAlex Bennée float32 int16_to_float32(int16_t, float_status *status);
156e5a41ffaSPeter Maydell float32 int32_to_float32(int32_t, float_status *status);
1572abdfe24SRichard Henderson float32 int64_to_float32(int64_t, float_status *status);
158c02e1fb8SAlex Bennée float32 uint16_to_float32(uint16_t, float_status *status);
159e5a41ffaSPeter Maydell float32 uint32_to_float32(uint32_t, float_status *status);
1602abdfe24SRichard Henderson float32 uint64_to_float32(uint64_t, float_status *status);
1612abdfe24SRichard Henderson 
1622abdfe24SRichard Henderson float64 int16_to_float64_scalbn(int16_t, int, float_status *status);
1632abdfe24SRichard Henderson float64 int32_to_float64_scalbn(int32_t, int, float_status *status);
1642abdfe24SRichard Henderson float64 int64_to_float64_scalbn(int64_t, int, float_status *status);
1652abdfe24SRichard Henderson float64 uint16_to_float64_scalbn(uint16_t, int, float_status *status);
1662abdfe24SRichard Henderson float64 uint32_to_float64_scalbn(uint32_t, int, float_status *status);
1672abdfe24SRichard Henderson float64 uint64_to_float64_scalbn(uint64_t, int, float_status *status);
1682abdfe24SRichard Henderson 
1692abdfe24SRichard Henderson float64 int16_to_float64(int16_t, float_status *status);
1702abdfe24SRichard Henderson float64 int32_to_float64(int32_t, float_status *status);
1712abdfe24SRichard Henderson float64 int64_to_float64(int64_t, float_status *status);
172c02e1fb8SAlex Bennée float64 uint16_to_float64(uint16_t, float_status *status);
173e5a41ffaSPeter Maydell float64 uint32_to_float64(uint32_t, float_status *status);
174e5a41ffaSPeter Maydell float64 uint64_to_float64(uint64_t, float_status *status);
1752abdfe24SRichard Henderson 
1762abdfe24SRichard Henderson floatx80 int32_to_floatx80(int32_t, float_status *status);
1772abdfe24SRichard Henderson floatx80 int64_to_floatx80(int64_t, float_status *status);
1782abdfe24SRichard Henderson 
1792abdfe24SRichard Henderson float128 int32_to_float128(int32_t, float_status *status);
1802abdfe24SRichard Henderson float128 int64_to_float128(int64_t, float_status *status);
181e5a41ffaSPeter Maydell float128 uint64_to_float128(uint64_t, float_status *status);
1826b4c305cSPaolo Bonzini 
1836b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1846b4c305cSPaolo Bonzini | Software half-precision conversion routines.
1856b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1862f6c74beSRichard Henderson 
1876fed16b2SAlex Bennée float16 float32_to_float16(float32, bool ieee, float_status *status);
1886fed16b2SAlex Bennée float32 float16_to_float32(float16, bool ieee, float_status *status);
1896fed16b2SAlex Bennée float16 float64_to_float16(float64 a, bool ieee, float_status *status);
1906fed16b2SAlex Bennée float64 float16_to_float64(float16 a, bool ieee, float_status *status);
1912f6c74beSRichard Henderson 
192*0d93d8ecSFrank Chang int8_t  float16_to_int8_scalbn(float16, FloatRoundMode, int,
193*0d93d8ecSFrank Chang                                float_status *status);
1943dede407SRichard Henderson int16_t float16_to_int16_scalbn(float16, FloatRoundMode, int, float_status *);
1953dede407SRichard Henderson int32_t float16_to_int32_scalbn(float16, FloatRoundMode, int, float_status *);
1963dede407SRichard Henderson int64_t float16_to_int64_scalbn(float16, FloatRoundMode, int, float_status *);
1972f6c74beSRichard Henderson 
198*0d93d8ecSFrank Chang int8_t  float16_to_int8(float16, float_status *status);
199ab52f973SAlex Bennée int16_t float16_to_int16(float16, float_status *status);
200ab52f973SAlex Bennée int32_t float16_to_int32(float16, float_status *status);
201ab52f973SAlex Bennée int64_t float16_to_int64(float16, float_status *status);
2022f6c74beSRichard Henderson 
2032f6c74beSRichard Henderson int16_t float16_to_int16_round_to_zero(float16, float_status *status);
2042f6c74beSRichard Henderson int32_t float16_to_int32_round_to_zero(float16, float_status *status);
205ab52f973SAlex Bennée int64_t float16_to_int64_round_to_zero(float16, float_status *status);
2062f6c74beSRichard Henderson 
207*0d93d8ecSFrank Chang uint8_t float16_to_uint8_scalbn(float16 a, FloatRoundMode,
208*0d93d8ecSFrank Chang                                 int, float_status *status);
2093dede407SRichard Henderson uint16_t float16_to_uint16_scalbn(float16 a, FloatRoundMode,
2103dede407SRichard Henderson                                   int, float_status *status);
2113dede407SRichard Henderson uint32_t float16_to_uint32_scalbn(float16 a, FloatRoundMode,
2123dede407SRichard Henderson                                   int, float_status *status);
2133dede407SRichard Henderson uint64_t float16_to_uint64_scalbn(float16 a, FloatRoundMode,
2143dede407SRichard Henderson                                   int, float_status *status);
2152f6c74beSRichard Henderson 
216*0d93d8ecSFrank Chang uint8_t  float16_to_uint8(float16 a, float_status *status);
2172f6c74beSRichard Henderson uint16_t float16_to_uint16(float16 a, float_status *status);
2182f6c74beSRichard Henderson uint32_t float16_to_uint32(float16 a, float_status *status);
2192f6c74beSRichard Henderson uint64_t float16_to_uint64(float16 a, float_status *status);
2202f6c74beSRichard Henderson 
2212f6c74beSRichard Henderson uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status);
2222f6c74beSRichard Henderson uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status);
223ab52f973SAlex Bennée uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status);
2246b4c305cSPaolo Bonzini 
2256b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
2266b4c305cSPaolo Bonzini | Software half-precision operations.
2276b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
2286fff2167SAlex Bennée 
229dbe4d53aSAlex Bennée float16 float16_round_to_int(float16, float_status *status);
2306fff2167SAlex Bennée float16 float16_add(float16, float16, float_status *status);
2316fff2167SAlex Bennée float16 float16_sub(float16, float16, float_status *status);
23274d707e2SAlex Bennée float16 float16_mul(float16, float16, float_status *status);
233d446830aSAlex Bennée float16 float16_muladd(float16, float16, float16, int, float_status *status);
234cf07323dSAlex Bennée float16 float16_div(float16, float16, float_status *status);
2350bfc9f19SAlex Bennée float16 float16_scalbn(float16, int, float_status *status);
23689360067SAlex Bennée float16 float16_min(float16, float16, float_status *status);
23789360067SAlex Bennée float16 float16_max(float16, float16, float_status *status);
23889360067SAlex Bennée float16 float16_minnum(float16, float16, float_status *status);
23989360067SAlex Bennée float16 float16_maxnum(float16, float16, float_status *status);
24089360067SAlex Bennée float16 float16_minnummag(float16, float16, float_status *status);
24189360067SAlex Bennée float16 float16_maxnummag(float16, float16, float_status *status);
242c13bb2daSAlex Bennée float16 float16_sqrt(float16, float_status *status);
24371bfd65cSRichard Henderson FloatRelation float16_compare(float16, float16, float_status *status);
24471bfd65cSRichard Henderson FloatRelation float16_compare_quiet(float16, float16, float_status *status);
2456fff2167SAlex Bennée 
246150c7a91SRichard Henderson bool float16_is_quiet_nan(float16, float_status *status);
247150c7a91SRichard Henderson bool float16_is_signaling_nan(float16, float_status *status);
248d619bb98SRichard Henderson float16 float16_silence_nan(float16, float_status *status);
2496b4c305cSPaolo Bonzini 
250150c7a91SRichard Henderson static inline bool float16_is_any_nan(float16 a)
2516b4c305cSPaolo Bonzini {
2526b4c305cSPaolo Bonzini     return ((float16_val(a) & ~0x8000) > 0x7c00);
2536b4c305cSPaolo Bonzini }
2546b4c305cSPaolo Bonzini 
255150c7a91SRichard Henderson static inline bool float16_is_neg(float16 a)
256f566c047SBharata B Rao {
257f566c047SBharata B Rao     return float16_val(a) >> 15;
258f566c047SBharata B Rao }
259f566c047SBharata B Rao 
260150c7a91SRichard Henderson static inline bool float16_is_infinity(float16 a)
261f566c047SBharata B Rao {
262f566c047SBharata B Rao     return (float16_val(a) & 0x7fff) == 0x7c00;
263f566c047SBharata B Rao }
264f566c047SBharata B Rao 
265150c7a91SRichard Henderson static inline bool float16_is_zero(float16 a)
266f566c047SBharata B Rao {
267f566c047SBharata B Rao     return (float16_val(a) & 0x7fff) == 0;
268f566c047SBharata B Rao }
269f566c047SBharata B Rao 
270150c7a91SRichard Henderson static inline bool float16_is_zero_or_denormal(float16 a)
271f566c047SBharata B Rao {
272f566c047SBharata B Rao     return (float16_val(a) & 0x7c00) == 0;
273f566c047SBharata B Rao }
274f566c047SBharata B Rao 
27528136775SAlex Bennée static inline float16 float16_abs(float16 a)
27628136775SAlex Bennée {
27728136775SAlex Bennée     /* Note that abs does *not* handle NaN specially, nor does
27828136775SAlex Bennée      * it flush denormal inputs to zero.
27928136775SAlex Bennée      */
28028136775SAlex Bennée     return make_float16(float16_val(a) & 0x7fff);
28128136775SAlex Bennée }
2825f10aef5SAlex Bennée 
2835f10aef5SAlex Bennée static inline float16 float16_chs(float16 a)
2845f10aef5SAlex Bennée {
2855f10aef5SAlex Bennée     /* Note that chs does *not* handle NaN specially, nor does
2865f10aef5SAlex Bennée      * it flush denormal inputs to zero.
2875f10aef5SAlex Bennée      */
2885f10aef5SAlex Bennée     return make_float16(float16_val(a) ^ 0x8000);
2895f10aef5SAlex Bennée }
2905f10aef5SAlex Bennée 
29178b5a3e6SAlex Bennée static inline float16 float16_set_sign(float16 a, int sign)
29278b5a3e6SAlex Bennée {
29378b5a3e6SAlex Bennée     return make_float16((float16_val(a) & 0x7fff) | (sign << 15));
29478b5a3e6SAlex Bennée }
29578b5a3e6SAlex Bennée 
296dd205025SKito Cheng static inline bool float16_eq(float16 a, float16 b, float_status *s)
297dd205025SKito Cheng {
298dd205025SKito Cheng     return float16_compare(a, b, s) == float_relation_equal;
299dd205025SKito Cheng }
300dd205025SKito Cheng 
301dd205025SKito Cheng static inline bool float16_le(float16 a, float16 b, float_status *s)
302dd205025SKito Cheng {
303dd205025SKito Cheng     return float16_compare(a, b, s) <= float_relation_equal;
304dd205025SKito Cheng }
305dd205025SKito Cheng 
306dd205025SKito Cheng static inline bool float16_lt(float16 a, float16 b, float_status *s)
307dd205025SKito Cheng {
308dd205025SKito Cheng     return float16_compare(a, b, s) < float_relation_equal;
309dd205025SKito Cheng }
310dd205025SKito Cheng 
311dd205025SKito Cheng static inline bool float16_unordered(float16 a, float16 b, float_status *s)
312dd205025SKito Cheng {
313dd205025SKito Cheng     return float16_compare(a, b, s) == float_relation_unordered;
314dd205025SKito Cheng }
315dd205025SKito Cheng 
316dd205025SKito Cheng static inline bool float16_eq_quiet(float16 a, float16 b, float_status *s)
317dd205025SKito Cheng {
318dd205025SKito Cheng     return float16_compare_quiet(a, b, s) == float_relation_equal;
319dd205025SKito Cheng }
320dd205025SKito Cheng 
321dd205025SKito Cheng static inline bool float16_le_quiet(float16 a, float16 b, float_status *s)
322dd205025SKito Cheng {
323dd205025SKito Cheng     return float16_compare_quiet(a, b, s) <= float_relation_equal;
324dd205025SKito Cheng }
325dd205025SKito Cheng 
326dd205025SKito Cheng static inline bool float16_lt_quiet(float16 a, float16 b, float_status *s)
327dd205025SKito Cheng {
328dd205025SKito Cheng     return float16_compare_quiet(a, b, s) < float_relation_equal;
329dd205025SKito Cheng }
330dd205025SKito Cheng 
331dd205025SKito Cheng static inline bool float16_unordered_quiet(float16 a, float16 b,
332dd205025SKito Cheng                                            float_status *s)
333dd205025SKito Cheng {
334dd205025SKito Cheng     return float16_compare_quiet(a, b, s) == float_relation_unordered;
335dd205025SKito Cheng }
336dd205025SKito Cheng 
337efd4829eSAlex Bennée #define float16_zero make_float16(0)
338efd4829eSAlex Bennée #define float16_half make_float16(0x3800)
339026e2d6eSAlex Bennée #define float16_one make_float16(0x3c00)
340026e2d6eSAlex Bennée #define float16_one_point_five make_float16(0x3e00)
341026e2d6eSAlex Bennée #define float16_two make_float16(0x4000)
342026e2d6eSAlex Bennée #define float16_three make_float16(0x4200)
343efd4829eSAlex Bennée #define float16_infinity make_float16(0x7c00)
344efd4829eSAlex Bennée 
3456b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3466b4c305cSPaolo Bonzini | The pattern for a default generated half-precision NaN.
3476b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
348af39bc8cSAleksandar Markovic float16 float16_default_nan(float_status *status);
3496b4c305cSPaolo Bonzini 
3506b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3516b4c305cSPaolo Bonzini | Software IEC/IEEE single-precision conversion routines.
3526b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
3532f6c74beSRichard Henderson 
3543dede407SRichard Henderson int16_t float32_to_int16_scalbn(float32, FloatRoundMode, int, float_status *);
3553dede407SRichard Henderson int32_t float32_to_int32_scalbn(float32, FloatRoundMode, int, float_status *);
3563dede407SRichard Henderson int64_t float32_to_int64_scalbn(float32, FloatRoundMode, int, float_status *);
3572f6c74beSRichard Henderson 
3580bb721d7SPeter Maydell int16_t float32_to_int16(float32, float_status *status);
359f4014512SPeter Maydell int32_t float32_to_int32(float32, float_status *status);
360f42c2224SPeter Maydell int64_t float32_to_int64(float32, float_status *status);
3612f6c74beSRichard Henderson 
3622f6c74beSRichard Henderson int16_t float32_to_int16_round_to_zero(float32, float_status *status);
3632f6c74beSRichard Henderson int32_t float32_to_int32_round_to_zero(float32, float_status *status);
364f42c2224SPeter Maydell int64_t float32_to_int64_round_to_zero(float32, float_status *status);
3652f6c74beSRichard Henderson 
3663dede407SRichard Henderson uint16_t float32_to_uint16_scalbn(float32, FloatRoundMode, int, float_status *);
3673dede407SRichard Henderson uint32_t float32_to_uint32_scalbn(float32, FloatRoundMode, int, float_status *);
3683dede407SRichard Henderson uint64_t float32_to_uint64_scalbn(float32, FloatRoundMode, int, float_status *);
3692f6c74beSRichard Henderson 
3702f6c74beSRichard Henderson uint16_t float32_to_uint16(float32, float_status *status);
3712f6c74beSRichard Henderson uint32_t float32_to_uint32(float32, float_status *status);
3722f6c74beSRichard Henderson uint64_t float32_to_uint64(float32, float_status *status);
3732f6c74beSRichard Henderson 
3742f6c74beSRichard Henderson uint16_t float32_to_uint16_round_to_zero(float32, float_status *status);
3752f6c74beSRichard Henderson uint32_t float32_to_uint32_round_to_zero(float32, float_status *status);
3762f6c74beSRichard Henderson uint64_t float32_to_uint64_round_to_zero(float32, float_status *status);
3772f6c74beSRichard Henderson 
378e5a41ffaSPeter Maydell float64 float32_to_float64(float32, float_status *status);
379e5a41ffaSPeter Maydell floatx80 float32_to_floatx80(float32, float_status *status);
380e5a41ffaSPeter Maydell float128 float32_to_float128(float32, float_status *status);
3816b4c305cSPaolo Bonzini 
3826b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3836b4c305cSPaolo Bonzini | Software IEC/IEEE single-precision operations.
3846b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
385e5a41ffaSPeter Maydell float32 float32_round_to_int(float32, float_status *status);
386e5a41ffaSPeter Maydell float32 float32_add(float32, float32, float_status *status);
387e5a41ffaSPeter Maydell float32 float32_sub(float32, float32, float_status *status);
388e5a41ffaSPeter Maydell float32 float32_mul(float32, float32, float_status *status);
389e5a41ffaSPeter Maydell float32 float32_div(float32, float32, float_status *status);
390e5a41ffaSPeter Maydell float32 float32_rem(float32, float32, float_status *status);
391e5a41ffaSPeter Maydell float32 float32_muladd(float32, float32, float32, int, float_status *status);
392e5a41ffaSPeter Maydell float32 float32_sqrt(float32, float_status *status);
393e5a41ffaSPeter Maydell float32 float32_exp2(float32, float_status *status);
394e5a41ffaSPeter Maydell float32 float32_log2(float32, float_status *status);
39571bfd65cSRichard Henderson FloatRelation float32_compare(float32, float32, float_status *status);
39671bfd65cSRichard Henderson FloatRelation float32_compare_quiet(float32, float32, float_status *status);
397e5a41ffaSPeter Maydell float32 float32_min(float32, float32, float_status *status);
398e5a41ffaSPeter Maydell float32 float32_max(float32, float32, float_status *status);
399e5a41ffaSPeter Maydell float32 float32_minnum(float32, float32, float_status *status);
400e5a41ffaSPeter Maydell float32 float32_maxnum(float32, float32, float_status *status);
401e5a41ffaSPeter Maydell float32 float32_minnummag(float32, float32, float_status *status);
402e5a41ffaSPeter Maydell float32 float32_maxnummag(float32, float32, float_status *status);
403150c7a91SRichard Henderson bool float32_is_quiet_nan(float32, float_status *status);
404150c7a91SRichard Henderson bool float32_is_signaling_nan(float32, float_status *status);
405d619bb98SRichard Henderson float32 float32_silence_nan(float32, float_status *status);
406e5a41ffaSPeter Maydell float32 float32_scalbn(float32, int, float_status *status);
4076b4c305cSPaolo Bonzini 
408a49db98dSLuiz Capitulino static inline float32 float32_abs(float32 a)
4096b4c305cSPaolo Bonzini {
4106b4c305cSPaolo Bonzini     /* Note that abs does *not* handle NaN specially, nor does
4116b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
4126b4c305cSPaolo Bonzini      */
4136b4c305cSPaolo Bonzini     return make_float32(float32_val(a) & 0x7fffffff);
4146b4c305cSPaolo Bonzini }
4156b4c305cSPaolo Bonzini 
416a49db98dSLuiz Capitulino static inline float32 float32_chs(float32 a)
4176b4c305cSPaolo Bonzini {
4186b4c305cSPaolo Bonzini     /* Note that chs does *not* handle NaN specially, nor does
4196b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
4206b4c305cSPaolo Bonzini      */
4216b4c305cSPaolo Bonzini     return make_float32(float32_val(a) ^ 0x80000000);
4226b4c305cSPaolo Bonzini }
4236b4c305cSPaolo Bonzini 
424150c7a91SRichard Henderson static inline bool float32_is_infinity(float32 a)
4256b4c305cSPaolo Bonzini {
4266b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7fffffff) == 0x7f800000;
4276b4c305cSPaolo Bonzini }
4286b4c305cSPaolo Bonzini 
429150c7a91SRichard Henderson static inline bool float32_is_neg(float32 a)
4306b4c305cSPaolo Bonzini {
4316b4c305cSPaolo Bonzini     return float32_val(a) >> 31;
4326b4c305cSPaolo Bonzini }
4336b4c305cSPaolo Bonzini 
434150c7a91SRichard Henderson static inline bool float32_is_zero(float32 a)
4356b4c305cSPaolo Bonzini {
4366b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7fffffff) == 0;
4376b4c305cSPaolo Bonzini }
4386b4c305cSPaolo Bonzini 
439150c7a91SRichard Henderson static inline bool float32_is_any_nan(float32 a)
4406b4c305cSPaolo Bonzini {
4416b4c305cSPaolo Bonzini     return ((float32_val(a) & ~(1 << 31)) > 0x7f800000UL);
4426b4c305cSPaolo Bonzini }
4436b4c305cSPaolo Bonzini 
444150c7a91SRichard Henderson static inline bool float32_is_zero_or_denormal(float32 a)
4456b4c305cSPaolo Bonzini {
4466b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7f800000) == 0;
4476b4c305cSPaolo Bonzini }
4486b4c305cSPaolo Bonzini 
449588e6dfdSEmilio G. Cota static inline bool float32_is_normal(float32 a)
450588e6dfdSEmilio G. Cota {
45147393181SDavid Hildenbrand     return (((float32_val(a) >> 23) + 1) & 0xff) >= 2;
452588e6dfdSEmilio G. Cota }
453588e6dfdSEmilio G. Cota 
454588e6dfdSEmilio G. Cota static inline bool float32_is_denormal(float32 a)
455588e6dfdSEmilio G. Cota {
456588e6dfdSEmilio G. Cota     return float32_is_zero_or_denormal(a) && !float32_is_zero(a);
457588e6dfdSEmilio G. Cota }
458588e6dfdSEmilio G. Cota 
459315df0d1SEmilio G. Cota static inline bool float32_is_zero_or_normal(float32 a)
460315df0d1SEmilio G. Cota {
461315df0d1SEmilio G. Cota     return float32_is_normal(a) || float32_is_zero(a);
462315df0d1SEmilio G. Cota }
463315df0d1SEmilio G. Cota 
464a49db98dSLuiz Capitulino static inline float32 float32_set_sign(float32 a, int sign)
4656b4c305cSPaolo Bonzini {
4666b4c305cSPaolo Bonzini     return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
4676b4c305cSPaolo Bonzini }
4686b4c305cSPaolo Bonzini 
4695da2d2d8SRichard Henderson static inline bool float32_eq(float32 a, float32 b, float_status *s)
4705da2d2d8SRichard Henderson {
4715da2d2d8SRichard Henderson     return float32_compare(a, b, s) == float_relation_equal;
4725da2d2d8SRichard Henderson }
4735da2d2d8SRichard Henderson 
4745da2d2d8SRichard Henderson static inline bool float32_le(float32 a, float32 b, float_status *s)
4755da2d2d8SRichard Henderson {
4765da2d2d8SRichard Henderson     return float32_compare(a, b, s) <= float_relation_equal;
4775da2d2d8SRichard Henderson }
4785da2d2d8SRichard Henderson 
4795da2d2d8SRichard Henderson static inline bool float32_lt(float32 a, float32 b, float_status *s)
4805da2d2d8SRichard Henderson {
4815da2d2d8SRichard Henderson     return float32_compare(a, b, s) < float_relation_equal;
4825da2d2d8SRichard Henderson }
4835da2d2d8SRichard Henderson 
4845da2d2d8SRichard Henderson static inline bool float32_unordered(float32 a, float32 b, float_status *s)
4855da2d2d8SRichard Henderson {
4865da2d2d8SRichard Henderson     return float32_compare(a, b, s) == float_relation_unordered;
4875da2d2d8SRichard Henderson }
4885da2d2d8SRichard Henderson 
4895da2d2d8SRichard Henderson static inline bool float32_eq_quiet(float32 a, float32 b, float_status *s)
4905da2d2d8SRichard Henderson {
4915da2d2d8SRichard Henderson     return float32_compare_quiet(a, b, s) == float_relation_equal;
4925da2d2d8SRichard Henderson }
4935da2d2d8SRichard Henderson 
4945da2d2d8SRichard Henderson static inline bool float32_le_quiet(float32 a, float32 b, float_status *s)
4955da2d2d8SRichard Henderson {
4965da2d2d8SRichard Henderson     return float32_compare_quiet(a, b, s) <= float_relation_equal;
4975da2d2d8SRichard Henderson }
4985da2d2d8SRichard Henderson 
4995da2d2d8SRichard Henderson static inline bool float32_lt_quiet(float32 a, float32 b, float_status *s)
5005da2d2d8SRichard Henderson {
5015da2d2d8SRichard Henderson     return float32_compare_quiet(a, b, s) < float_relation_equal;
5025da2d2d8SRichard Henderson }
5035da2d2d8SRichard Henderson 
5045da2d2d8SRichard Henderson static inline bool float32_unordered_quiet(float32 a, float32 b,
5055da2d2d8SRichard Henderson                                            float_status *s)
5065da2d2d8SRichard Henderson {
5075da2d2d8SRichard Henderson     return float32_compare_quiet(a, b, s) == float_relation_unordered;
5085da2d2d8SRichard Henderson }
5095da2d2d8SRichard Henderson 
5106b4c305cSPaolo Bonzini #define float32_zero make_float32(0)
5116b4c305cSPaolo Bonzini #define float32_half make_float32(0x3f000000)
512026e2d6eSAlex Bennée #define float32_one make_float32(0x3f800000)
513026e2d6eSAlex Bennée #define float32_one_point_five make_float32(0x3fc00000)
514026e2d6eSAlex Bennée #define float32_two make_float32(0x40000000)
515026e2d6eSAlex Bennée #define float32_three make_float32(0x40400000)
5166b4c305cSPaolo Bonzini #define float32_infinity make_float32(0x7f800000)
5176b4c305cSPaolo Bonzini 
5186b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
51988857acaSLaurent Vivier | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
52088857acaSLaurent Vivier | single-precision floating-point value, returning the result.  After being
52188857acaSLaurent Vivier | shifted into the proper positions, the three fields are simply added
52288857acaSLaurent Vivier | together to form the result.  This means that any integer portion of `zSig'
52388857acaSLaurent Vivier | will be added into the exponent.  Since a properly normalized significand
52488857acaSLaurent Vivier | will have an integer portion equal to 1, the `zExp' input should be 1 less
52588857acaSLaurent Vivier | than the desired result exponent whenever `zSig' is a complete, normalized
52688857acaSLaurent Vivier | significand.
52788857acaSLaurent Vivier *----------------------------------------------------------------------------*/
52888857acaSLaurent Vivier 
529c120391cSRichard Henderson static inline float32 packFloat32(bool zSign, int zExp, uint32_t zSig)
53088857acaSLaurent Vivier {
53188857acaSLaurent Vivier     return make_float32(
53288857acaSLaurent Vivier           (((uint32_t)zSign) << 31) + (((uint32_t)zExp) << 23) + zSig);
53388857acaSLaurent Vivier }
53488857acaSLaurent Vivier 
53588857acaSLaurent Vivier /*----------------------------------------------------------------------------
5366b4c305cSPaolo Bonzini | The pattern for a default generated single-precision NaN.
5376b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
538af39bc8cSAleksandar Markovic float32 float32_default_nan(float_status *status);
5396b4c305cSPaolo Bonzini 
5406b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
5416b4c305cSPaolo Bonzini | Software IEC/IEEE double-precision conversion routines.
5426b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
5432f6c74beSRichard Henderson 
5443dede407SRichard Henderson int16_t float64_to_int16_scalbn(float64, FloatRoundMode, int, float_status *);
5453dede407SRichard Henderson int32_t float64_to_int32_scalbn(float64, FloatRoundMode, int, float_status *);
5463dede407SRichard Henderson int64_t float64_to_int64_scalbn(float64, FloatRoundMode, int, float_status *);
5472f6c74beSRichard Henderson 
5480bb721d7SPeter Maydell int16_t float64_to_int16(float64, float_status *status);
549f4014512SPeter Maydell int32_t float64_to_int32(float64, float_status *status);
550f42c2224SPeter Maydell int64_t float64_to_int64(float64, float_status *status);
5512f6c74beSRichard Henderson 
5522f6c74beSRichard Henderson int16_t float64_to_int16_round_to_zero(float64, float_status *status);
5532f6c74beSRichard Henderson int32_t float64_to_int32_round_to_zero(float64, float_status *status);
554f42c2224SPeter Maydell int64_t float64_to_int64_round_to_zero(float64, float_status *status);
5552f6c74beSRichard Henderson 
5563dede407SRichard Henderson uint16_t float64_to_uint16_scalbn(float64, FloatRoundMode, int, float_status *);
5573dede407SRichard Henderson uint32_t float64_to_uint32_scalbn(float64, FloatRoundMode, int, float_status *);
5583dede407SRichard Henderson uint64_t float64_to_uint64_scalbn(float64, FloatRoundMode, int, float_status *);
5592f6c74beSRichard Henderson 
5602f6c74beSRichard Henderson uint16_t float64_to_uint16(float64, float_status *status);
5612f6c74beSRichard Henderson uint32_t float64_to_uint32(float64, float_status *status);
5622f6c74beSRichard Henderson uint64_t float64_to_uint64(float64, float_status *status);
5632f6c74beSRichard Henderson 
5642f6c74beSRichard Henderson uint16_t float64_to_uint16_round_to_zero(float64, float_status *status);
5652f6c74beSRichard Henderson uint32_t float64_to_uint32_round_to_zero(float64, float_status *status);
5662f6c74beSRichard Henderson uint64_t float64_to_uint64_round_to_zero(float64, float_status *status);
5672f6c74beSRichard Henderson 
568e5a41ffaSPeter Maydell float32 float64_to_float32(float64, float_status *status);
569e5a41ffaSPeter Maydell floatx80 float64_to_floatx80(float64, float_status *status);
570e5a41ffaSPeter Maydell float128 float64_to_float128(float64, float_status *status);
5716b4c305cSPaolo Bonzini 
5726b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
5736b4c305cSPaolo Bonzini | Software IEC/IEEE double-precision operations.
5746b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
575e5a41ffaSPeter Maydell float64 float64_round_to_int(float64, float_status *status);
576e5a41ffaSPeter Maydell float64 float64_add(float64, float64, float_status *status);
577e5a41ffaSPeter Maydell float64 float64_sub(float64, float64, float_status *status);
578e5a41ffaSPeter Maydell float64 float64_mul(float64, float64, float_status *status);
579e5a41ffaSPeter Maydell float64 float64_div(float64, float64, float_status *status);
580e5a41ffaSPeter Maydell float64 float64_rem(float64, float64, float_status *status);
581e5a41ffaSPeter Maydell float64 float64_muladd(float64, float64, float64, int, float_status *status);
582e5a41ffaSPeter Maydell float64 float64_sqrt(float64, float_status *status);
583e5a41ffaSPeter Maydell float64 float64_log2(float64, float_status *status);
58471bfd65cSRichard Henderson FloatRelation float64_compare(float64, float64, float_status *status);
58571bfd65cSRichard Henderson FloatRelation float64_compare_quiet(float64, float64, float_status *status);
586e5a41ffaSPeter Maydell float64 float64_min(float64, float64, float_status *status);
587e5a41ffaSPeter Maydell float64 float64_max(float64, float64, float_status *status);
588e5a41ffaSPeter Maydell float64 float64_minnum(float64, float64, float_status *status);
589e5a41ffaSPeter Maydell float64 float64_maxnum(float64, float64, float_status *status);
590e5a41ffaSPeter Maydell float64 float64_minnummag(float64, float64, float_status *status);
591e5a41ffaSPeter Maydell float64 float64_maxnummag(float64, float64, float_status *status);
592150c7a91SRichard Henderson bool float64_is_quiet_nan(float64 a, float_status *status);
593150c7a91SRichard Henderson bool float64_is_signaling_nan(float64, float_status *status);
594d619bb98SRichard Henderson float64 float64_silence_nan(float64, float_status *status);
595e5a41ffaSPeter Maydell float64 float64_scalbn(float64, int, float_status *status);
5966b4c305cSPaolo Bonzini 
597a49db98dSLuiz Capitulino static inline float64 float64_abs(float64 a)
5986b4c305cSPaolo Bonzini {
5996b4c305cSPaolo Bonzini     /* Note that abs does *not* handle NaN specially, nor does
6006b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
6016b4c305cSPaolo Bonzini      */
6026b4c305cSPaolo Bonzini     return make_float64(float64_val(a) & 0x7fffffffffffffffLL);
6036b4c305cSPaolo Bonzini }
6046b4c305cSPaolo Bonzini 
605a49db98dSLuiz Capitulino static inline float64 float64_chs(float64 a)
6066b4c305cSPaolo Bonzini {
6076b4c305cSPaolo Bonzini     /* Note that chs does *not* handle NaN specially, nor does
6086b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
6096b4c305cSPaolo Bonzini      */
6106b4c305cSPaolo Bonzini     return make_float64(float64_val(a) ^ 0x8000000000000000LL);
6116b4c305cSPaolo Bonzini }
6126b4c305cSPaolo Bonzini 
613150c7a91SRichard Henderson static inline bool float64_is_infinity(float64 a)
6146b4c305cSPaolo Bonzini {
6156b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL;
6166b4c305cSPaolo Bonzini }
6176b4c305cSPaolo Bonzini 
618150c7a91SRichard Henderson static inline bool float64_is_neg(float64 a)
6196b4c305cSPaolo Bonzini {
6206b4c305cSPaolo Bonzini     return float64_val(a) >> 63;
6216b4c305cSPaolo Bonzini }
6226b4c305cSPaolo Bonzini 
623150c7a91SRichard Henderson static inline bool float64_is_zero(float64 a)
6246b4c305cSPaolo Bonzini {
6256b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7fffffffffffffffLL) == 0;
6266b4c305cSPaolo Bonzini }
6276b4c305cSPaolo Bonzini 
628150c7a91SRichard Henderson static inline bool float64_is_any_nan(float64 a)
6296b4c305cSPaolo Bonzini {
6306b4c305cSPaolo Bonzini     return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL);
6316b4c305cSPaolo Bonzini }
6326b4c305cSPaolo Bonzini 
633150c7a91SRichard Henderson static inline bool float64_is_zero_or_denormal(float64 a)
6346b4c305cSPaolo Bonzini {
6356b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7ff0000000000000LL) == 0;
6366b4c305cSPaolo Bonzini }
6376b4c305cSPaolo Bonzini 
638588e6dfdSEmilio G. Cota static inline bool float64_is_normal(float64 a)
639588e6dfdSEmilio G. Cota {
64047393181SDavid Hildenbrand     return (((float64_val(a) >> 52) + 1) & 0x7ff) >= 2;
641588e6dfdSEmilio G. Cota }
642588e6dfdSEmilio G. Cota 
643588e6dfdSEmilio G. Cota static inline bool float64_is_denormal(float64 a)
644588e6dfdSEmilio G. Cota {
645588e6dfdSEmilio G. Cota     return float64_is_zero_or_denormal(a) && !float64_is_zero(a);
646588e6dfdSEmilio G. Cota }
647588e6dfdSEmilio G. Cota 
648315df0d1SEmilio G. Cota static inline bool float64_is_zero_or_normal(float64 a)
649315df0d1SEmilio G. Cota {
650315df0d1SEmilio G. Cota     return float64_is_normal(a) || float64_is_zero(a);
651315df0d1SEmilio G. Cota }
652315df0d1SEmilio G. Cota 
653a49db98dSLuiz Capitulino static inline float64 float64_set_sign(float64 a, int sign)
6546b4c305cSPaolo Bonzini {
6556b4c305cSPaolo Bonzini     return make_float64((float64_val(a) & 0x7fffffffffffffffULL)
6566b4c305cSPaolo Bonzini                         | ((int64_t)sign << 63));
6576b4c305cSPaolo Bonzini }
6586b4c305cSPaolo Bonzini 
6590673ecdfSRichard Henderson static inline bool float64_eq(float64 a, float64 b, float_status *s)
6600673ecdfSRichard Henderson {
6610673ecdfSRichard Henderson     return float64_compare(a, b, s) == float_relation_equal;
6620673ecdfSRichard Henderson }
6630673ecdfSRichard Henderson 
6640673ecdfSRichard Henderson static inline bool float64_le(float64 a, float64 b, float_status *s)
6650673ecdfSRichard Henderson {
6660673ecdfSRichard Henderson     return float64_compare(a, b, s) <= float_relation_equal;
6670673ecdfSRichard Henderson }
6680673ecdfSRichard Henderson 
6690673ecdfSRichard Henderson static inline bool float64_lt(float64 a, float64 b, float_status *s)
6700673ecdfSRichard Henderson {
6710673ecdfSRichard Henderson     return float64_compare(a, b, s) < float_relation_equal;
6720673ecdfSRichard Henderson }
6730673ecdfSRichard Henderson 
6740673ecdfSRichard Henderson static inline bool float64_unordered(float64 a, float64 b, float_status *s)
6750673ecdfSRichard Henderson {
6760673ecdfSRichard Henderson     return float64_compare(a, b, s) == float_relation_unordered;
6770673ecdfSRichard Henderson }
6780673ecdfSRichard Henderson 
6790673ecdfSRichard Henderson static inline bool float64_eq_quiet(float64 a, float64 b, float_status *s)
6800673ecdfSRichard Henderson {
6810673ecdfSRichard Henderson     return float64_compare_quiet(a, b, s) == float_relation_equal;
6820673ecdfSRichard Henderson }
6830673ecdfSRichard Henderson 
6840673ecdfSRichard Henderson static inline bool float64_le_quiet(float64 a, float64 b, float_status *s)
6850673ecdfSRichard Henderson {
6860673ecdfSRichard Henderson     return float64_compare_quiet(a, b, s) <= float_relation_equal;
6870673ecdfSRichard Henderson }
6880673ecdfSRichard Henderson 
6890673ecdfSRichard Henderson static inline bool float64_lt_quiet(float64 a, float64 b, float_status *s)
6900673ecdfSRichard Henderson {
6910673ecdfSRichard Henderson     return float64_compare_quiet(a, b, s) < float_relation_equal;
6920673ecdfSRichard Henderson }
6930673ecdfSRichard Henderson 
6940673ecdfSRichard Henderson static inline bool float64_unordered_quiet(float64 a, float64 b,
6950673ecdfSRichard Henderson                                            float_status *s)
6960673ecdfSRichard Henderson {
6970673ecdfSRichard Henderson     return float64_compare_quiet(a, b, s) == float_relation_unordered;
6980673ecdfSRichard Henderson }
6990673ecdfSRichard Henderson 
7006b4c305cSPaolo Bonzini #define float64_zero make_float64(0)
7016b4c305cSPaolo Bonzini #define float64_half make_float64(0x3fe0000000000000LL)
702026e2d6eSAlex Bennée #define float64_one make_float64(0x3ff0000000000000LL)
703026e2d6eSAlex Bennée #define float64_one_point_five make_float64(0x3FF8000000000000ULL)
704026e2d6eSAlex Bennée #define float64_two make_float64(0x4000000000000000ULL)
705026e2d6eSAlex Bennée #define float64_three make_float64(0x4008000000000000ULL)
706026e2d6eSAlex Bennée #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
7076b4c305cSPaolo Bonzini #define float64_infinity make_float64(0x7ff0000000000000LL)
7086b4c305cSPaolo Bonzini 
7096b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
7106b4c305cSPaolo Bonzini | The pattern for a default generated double-precision NaN.
7116b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
712af39bc8cSAleksandar Markovic float64 float64_default_nan(float_status *status);
7136b4c305cSPaolo Bonzini 
7146b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
7156b4c305cSPaolo Bonzini | Software IEC/IEEE extended double-precision conversion routines.
7166b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
717f4014512SPeter Maydell int32_t floatx80_to_int32(floatx80, float_status *status);
718f4014512SPeter Maydell int32_t floatx80_to_int32_round_to_zero(floatx80, float_status *status);
719f42c2224SPeter Maydell int64_t floatx80_to_int64(floatx80, float_status *status);
720f42c2224SPeter Maydell int64_t floatx80_to_int64_round_to_zero(floatx80, float_status *status);
721e5a41ffaSPeter Maydell float32 floatx80_to_float32(floatx80, float_status *status);
722e5a41ffaSPeter Maydell float64 floatx80_to_float64(floatx80, float_status *status);
723e5a41ffaSPeter Maydell float128 floatx80_to_float128(floatx80, float_status *status);
7246b4c305cSPaolo Bonzini 
7256b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
7260f605c88SLaurent Vivier | The pattern for an extended double-precision inf.
7270f605c88SLaurent Vivier *----------------------------------------------------------------------------*/
7280f605c88SLaurent Vivier extern const floatx80 floatx80_infinity;
7290f605c88SLaurent Vivier 
7300f605c88SLaurent Vivier /*----------------------------------------------------------------------------
7316b4c305cSPaolo Bonzini | Software IEC/IEEE extended double-precision operations.
7326b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
7330f721292SLaurent Vivier floatx80 floatx80_round(floatx80 a, float_status *status);
734e5a41ffaSPeter Maydell floatx80 floatx80_round_to_int(floatx80, float_status *status);
735e5a41ffaSPeter Maydell floatx80 floatx80_add(floatx80, floatx80, float_status *status);
736e5a41ffaSPeter Maydell floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
737e5a41ffaSPeter Maydell floatx80 floatx80_mul(floatx80, floatx80, float_status *status);
738e5a41ffaSPeter Maydell floatx80 floatx80_div(floatx80, floatx80, float_status *status);
739445810ecSJoseph Myers floatx80 floatx80_modrem(floatx80, floatx80, bool, uint64_t *,
740445810ecSJoseph Myers                          float_status *status);
7416b8b0136SJoseph Myers floatx80 floatx80_mod(floatx80, floatx80, float_status *status);
742e5a41ffaSPeter Maydell floatx80 floatx80_rem(floatx80, floatx80, float_status *status);
743e5a41ffaSPeter Maydell floatx80 floatx80_sqrt(floatx80, float_status *status);
74471bfd65cSRichard Henderson FloatRelation floatx80_compare(floatx80, floatx80, float_status *status);
74571bfd65cSRichard Henderson FloatRelation floatx80_compare_quiet(floatx80, floatx80, float_status *status);
746af39bc8cSAleksandar Markovic int floatx80_is_quiet_nan(floatx80, float_status *status);
747af39bc8cSAleksandar Markovic int floatx80_is_signaling_nan(floatx80, float_status *status);
748d619bb98SRichard Henderson floatx80 floatx80_silence_nan(floatx80, float_status *status);
749e5a41ffaSPeter Maydell floatx80 floatx80_scalbn(floatx80, int, float_status *status);
7506b4c305cSPaolo Bonzini 
751a49db98dSLuiz Capitulino static inline floatx80 floatx80_abs(floatx80 a)
7526b4c305cSPaolo Bonzini {
7536b4c305cSPaolo Bonzini     a.high &= 0x7fff;
7546b4c305cSPaolo Bonzini     return a;
7556b4c305cSPaolo Bonzini }
7566b4c305cSPaolo Bonzini 
757a49db98dSLuiz Capitulino static inline floatx80 floatx80_chs(floatx80 a)
7586b4c305cSPaolo Bonzini {
7596b4c305cSPaolo Bonzini     a.high ^= 0x8000;
7606b4c305cSPaolo Bonzini     return a;
7616b4c305cSPaolo Bonzini }
7626b4c305cSPaolo Bonzini 
763150c7a91SRichard Henderson static inline bool floatx80_is_infinity(floatx80 a)
7646b4c305cSPaolo Bonzini {
7650f605c88SLaurent Vivier #if defined(TARGET_M68K)
7660f605c88SLaurent Vivier     return (a.high & 0x7fff) == floatx80_infinity.high && !(a.low << 1);
7670f605c88SLaurent Vivier #else
7680f605c88SLaurent Vivier     return (a.high & 0x7fff) == floatx80_infinity.high &&
7690f605c88SLaurent Vivier                        a.low == floatx80_infinity.low;
7700f605c88SLaurent Vivier #endif
7716b4c305cSPaolo Bonzini }
7726b4c305cSPaolo Bonzini 
773150c7a91SRichard Henderson static inline bool floatx80_is_neg(floatx80 a)
7746b4c305cSPaolo Bonzini {
7756b4c305cSPaolo Bonzini     return a.high >> 15;
7766b4c305cSPaolo Bonzini }
7776b4c305cSPaolo Bonzini 
778150c7a91SRichard Henderson static inline bool floatx80_is_zero(floatx80 a)
7796b4c305cSPaolo Bonzini {
7806b4c305cSPaolo Bonzini     return (a.high & 0x7fff) == 0 && a.low == 0;
7816b4c305cSPaolo Bonzini }
7826b4c305cSPaolo Bonzini 
783150c7a91SRichard Henderson static inline bool floatx80_is_zero_or_denormal(floatx80 a)
7846b4c305cSPaolo Bonzini {
7856b4c305cSPaolo Bonzini     return (a.high & 0x7fff) == 0;
7866b4c305cSPaolo Bonzini }
7876b4c305cSPaolo Bonzini 
788150c7a91SRichard Henderson static inline bool floatx80_is_any_nan(floatx80 a)
7896b4c305cSPaolo Bonzini {
7906b4c305cSPaolo Bonzini     return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
7916b4c305cSPaolo Bonzini }
7926b4c305cSPaolo Bonzini 
793c6baf650SRichard Henderson static inline bool floatx80_eq(floatx80 a, floatx80 b, float_status *s)
794c6baf650SRichard Henderson {
795c6baf650SRichard Henderson     return floatx80_compare(a, b, s) == float_relation_equal;
796c6baf650SRichard Henderson }
797c6baf650SRichard Henderson 
798c6baf650SRichard Henderson static inline bool floatx80_le(floatx80 a, floatx80 b, float_status *s)
799c6baf650SRichard Henderson {
800c6baf650SRichard Henderson     return floatx80_compare(a, b, s) <= float_relation_equal;
801c6baf650SRichard Henderson }
802c6baf650SRichard Henderson 
803c6baf650SRichard Henderson static inline bool floatx80_lt(floatx80 a, floatx80 b, float_status *s)
804c6baf650SRichard Henderson {
805c6baf650SRichard Henderson     return floatx80_compare(a, b, s) < float_relation_equal;
806c6baf650SRichard Henderson }
807c6baf650SRichard Henderson 
808c6baf650SRichard Henderson static inline bool floatx80_unordered(floatx80 a, floatx80 b, float_status *s)
809c6baf650SRichard Henderson {
810c6baf650SRichard Henderson     return floatx80_compare(a, b, s) == float_relation_unordered;
811c6baf650SRichard Henderson }
812c6baf650SRichard Henderson 
813c6baf650SRichard Henderson static inline bool floatx80_eq_quiet(floatx80 a, floatx80 b, float_status *s)
814c6baf650SRichard Henderson {
815c6baf650SRichard Henderson     return floatx80_compare_quiet(a, b, s) == float_relation_equal;
816c6baf650SRichard Henderson }
817c6baf650SRichard Henderson 
818c6baf650SRichard Henderson static inline bool floatx80_le_quiet(floatx80 a, floatx80 b, float_status *s)
819c6baf650SRichard Henderson {
820c6baf650SRichard Henderson     return floatx80_compare_quiet(a, b, s) <= float_relation_equal;
821c6baf650SRichard Henderson }
822c6baf650SRichard Henderson 
823c6baf650SRichard Henderson static inline bool floatx80_lt_quiet(floatx80 a, floatx80 b, float_status *s)
824c6baf650SRichard Henderson {
825c6baf650SRichard Henderson     return floatx80_compare_quiet(a, b, s) < float_relation_equal;
826c6baf650SRichard Henderson }
827c6baf650SRichard Henderson 
828c6baf650SRichard Henderson static inline bool floatx80_unordered_quiet(floatx80 a, floatx80 b,
829c6baf650SRichard Henderson                                            float_status *s)
830c6baf650SRichard Henderson {
831c6baf650SRichard Henderson     return floatx80_compare_quiet(a, b, s) == float_relation_unordered;
832c6baf650SRichard Henderson }
833c6baf650SRichard Henderson 
834d1eb8f2aSAndrew Dutcher /*----------------------------------------------------------------------------
835d1eb8f2aSAndrew Dutcher | Return whether the given value is an invalid floatx80 encoding.
836d1eb8f2aSAndrew Dutcher | Invalid floatx80 encodings arise when the integer bit is not set, but
837d1eb8f2aSAndrew Dutcher | the exponent is not zero. The only times the integer bit is permitted to
838d1eb8f2aSAndrew Dutcher | be zero is in subnormal numbers and the value zero.
839d1eb8f2aSAndrew Dutcher | This includes what the Intel software developer's manual calls pseudo-NaNs,
840d1eb8f2aSAndrew Dutcher | pseudo-infinities and un-normal numbers. It does not include
841d1eb8f2aSAndrew Dutcher | pseudo-denormals, which must still be correctly handled as inputs even
842d1eb8f2aSAndrew Dutcher | if they are never generated as outputs.
843d1eb8f2aSAndrew Dutcher *----------------------------------------------------------------------------*/
844d1eb8f2aSAndrew Dutcher static inline bool floatx80_invalid_encoding(floatx80 a)
845d1eb8f2aSAndrew Dutcher {
846d159dd05SLaurent Vivier #if defined(TARGET_M68K)
847d159dd05SLaurent Vivier     /*-------------------------------------------------------------------------
848d159dd05SLaurent Vivier     | With m68k, the explicit integer bit can be zero in the case of:
849d159dd05SLaurent Vivier     | - zeros                (exp == 0, mantissa == 0)
850d159dd05SLaurent Vivier     | - denormalized numbers (exp == 0, mantissa != 0)
851d159dd05SLaurent Vivier     | - unnormalized numbers (exp != 0, exp < 0x7FFF)
852d159dd05SLaurent Vivier     | - infinities           (exp == 0x7FFF, mantissa == 0)
853d159dd05SLaurent Vivier     | - not-a-numbers        (exp == 0x7FFF, mantissa != 0)
854d159dd05SLaurent Vivier     |
855d159dd05SLaurent Vivier     | For infinities and NaNs, the explicit integer bit can be either one or
856d159dd05SLaurent Vivier     | zero.
857d159dd05SLaurent Vivier     |
858d159dd05SLaurent Vivier     | The IEEE 754 standard does not define a zero integer bit. Such a number
859d159dd05SLaurent Vivier     | is an unnormalized number. Hardware does not directly support
860d159dd05SLaurent Vivier     | denormalized and unnormalized numbers, but implicitly supports them by
861d159dd05SLaurent Vivier     | trapping them as unimplemented data types, allowing efficient conversion
862d159dd05SLaurent Vivier     | in software.
863d159dd05SLaurent Vivier     |
864d159dd05SLaurent Vivier     | See "M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL",
865d159dd05SLaurent Vivier     |     "1.6 FLOATING-POINT DATA TYPES"
866d159dd05SLaurent Vivier     *------------------------------------------------------------------------*/
867d159dd05SLaurent Vivier     return false;
868d159dd05SLaurent Vivier #else
869d1eb8f2aSAndrew Dutcher     return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0;
870d159dd05SLaurent Vivier #endif
871d1eb8f2aSAndrew Dutcher }
872d1eb8f2aSAndrew Dutcher 
8736b4c305cSPaolo Bonzini #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
874163b3d1aSLaszlo Ersek #define floatx80_zero_init make_floatx80_init(0x0000, 0x0000000000000000LL)
8756b4c305cSPaolo Bonzini #define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
8766b4c305cSPaolo Bonzini #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
8776b4c305cSPaolo Bonzini #define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
8786b4c305cSPaolo Bonzini #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
8796b4c305cSPaolo Bonzini 
8806b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
88188857acaSLaurent Vivier | Returns the fraction bits of the extended double-precision floating-point
88288857acaSLaurent Vivier | value `a'.
88388857acaSLaurent Vivier *----------------------------------------------------------------------------*/
88488857acaSLaurent Vivier 
88588857acaSLaurent Vivier static inline uint64_t extractFloatx80Frac(floatx80 a)
88688857acaSLaurent Vivier {
88788857acaSLaurent Vivier     return a.low;
88888857acaSLaurent Vivier }
88988857acaSLaurent Vivier 
89088857acaSLaurent Vivier /*----------------------------------------------------------------------------
89188857acaSLaurent Vivier | Returns the exponent bits of the extended double-precision floating-point
89288857acaSLaurent Vivier | value `a'.
89388857acaSLaurent Vivier *----------------------------------------------------------------------------*/
89488857acaSLaurent Vivier 
89588857acaSLaurent Vivier static inline int32_t extractFloatx80Exp(floatx80 a)
89688857acaSLaurent Vivier {
89788857acaSLaurent Vivier     return a.high & 0x7FFF;
89888857acaSLaurent Vivier }
89988857acaSLaurent Vivier 
90088857acaSLaurent Vivier /*----------------------------------------------------------------------------
90188857acaSLaurent Vivier | Returns the sign bit of the extended double-precision floating-point value
90288857acaSLaurent Vivier | `a'.
90388857acaSLaurent Vivier *----------------------------------------------------------------------------*/
90488857acaSLaurent Vivier 
905c120391cSRichard Henderson static inline bool extractFloatx80Sign(floatx80 a)
90688857acaSLaurent Vivier {
90788857acaSLaurent Vivier     return a.high >> 15;
90888857acaSLaurent Vivier }
90988857acaSLaurent Vivier 
91088857acaSLaurent Vivier /*----------------------------------------------------------------------------
91188857acaSLaurent Vivier | Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
91288857acaSLaurent Vivier | extended double-precision floating-point value, returning the result.
91388857acaSLaurent Vivier *----------------------------------------------------------------------------*/
91488857acaSLaurent Vivier 
915c120391cSRichard Henderson static inline floatx80 packFloatx80(bool zSign, int32_t zExp, uint64_t zSig)
91688857acaSLaurent Vivier {
91788857acaSLaurent Vivier     floatx80 z;
91888857acaSLaurent Vivier 
91988857acaSLaurent Vivier     z.low = zSig;
92088857acaSLaurent Vivier     z.high = (((uint16_t)zSign) << 15) + zExp;
92188857acaSLaurent Vivier     return z;
92288857acaSLaurent Vivier }
92388857acaSLaurent Vivier 
92488857acaSLaurent Vivier /*----------------------------------------------------------------------------
92588857acaSLaurent Vivier | Normalizes the subnormal extended double-precision floating-point value
92688857acaSLaurent Vivier | represented by the denormalized significand `aSig'.  The normalized exponent
92788857acaSLaurent Vivier | and significand are stored at the locations pointed to by `zExpPtr' and
92888857acaSLaurent Vivier | `zSigPtr', respectively.
92988857acaSLaurent Vivier *----------------------------------------------------------------------------*/
93088857acaSLaurent Vivier 
93188857acaSLaurent Vivier void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
93288857acaSLaurent Vivier                                 uint64_t *zSigPtr);
93388857acaSLaurent Vivier 
93488857acaSLaurent Vivier /*----------------------------------------------------------------------------
93588857acaSLaurent Vivier | Takes two extended double-precision floating-point values `a' and `b', one
93688857acaSLaurent Vivier | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
93788857acaSLaurent Vivier | `b' is a signaling NaN, the invalid exception is raised.
93888857acaSLaurent Vivier *----------------------------------------------------------------------------*/
93988857acaSLaurent Vivier 
94088857acaSLaurent Vivier floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status);
94188857acaSLaurent Vivier 
94288857acaSLaurent Vivier /*----------------------------------------------------------------------------
94388857acaSLaurent Vivier | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
94488857acaSLaurent Vivier | and extended significand formed by the concatenation of `zSig0' and `zSig1',
94588857acaSLaurent Vivier | and returns the proper extended double-precision floating-point value
94688857acaSLaurent Vivier | corresponding to the abstract input.  Ordinarily, the abstract value is
94788857acaSLaurent Vivier | rounded and packed into the extended double-precision format, with the
94888857acaSLaurent Vivier | inexact exception raised if the abstract input cannot be represented
94988857acaSLaurent Vivier | exactly.  However, if the abstract value is too large, the overflow and
95088857acaSLaurent Vivier | inexact exceptions are raised and an infinity or maximal finite value is
95188857acaSLaurent Vivier | returned.  If the abstract value is too small, the input value is rounded to
95288857acaSLaurent Vivier | a subnormal number, and the underflow and inexact exceptions are raised if
95388857acaSLaurent Vivier | the abstract input cannot be represented exactly as a subnormal extended
95488857acaSLaurent Vivier | double-precision floating-point number.
95588857acaSLaurent Vivier |     If `roundingPrecision' is 32 or 64, the result is rounded to the same
95688857acaSLaurent Vivier | number of bits as single or double precision, respectively.  Otherwise, the
95788857acaSLaurent Vivier | result is rounded to the full precision of the extended double-precision
95888857acaSLaurent Vivier | format.
95988857acaSLaurent Vivier |     The input significand must be normalized or smaller.  If the input
96088857acaSLaurent Vivier | significand is not normalized, `zExp' must be 0; in that case, the result
96188857acaSLaurent Vivier | returned is a subnormal number, and it must not require rounding.  The
96288857acaSLaurent Vivier | handling of underflow and overflow follows the IEC/IEEE Standard for Binary
96388857acaSLaurent Vivier | Floating-Point Arithmetic.
96488857acaSLaurent Vivier *----------------------------------------------------------------------------*/
96588857acaSLaurent Vivier 
966c120391cSRichard Henderson floatx80 roundAndPackFloatx80(int8_t roundingPrecision, bool zSign,
96788857acaSLaurent Vivier                               int32_t zExp, uint64_t zSig0, uint64_t zSig1,
96888857acaSLaurent Vivier                               float_status *status);
96988857acaSLaurent Vivier 
97088857acaSLaurent Vivier /*----------------------------------------------------------------------------
97188857acaSLaurent Vivier | Takes an abstract floating-point value having sign `zSign', exponent
97288857acaSLaurent Vivier | `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
97388857acaSLaurent Vivier | and returns the proper extended double-precision floating-point value
97488857acaSLaurent Vivier | corresponding to the abstract input.  This routine is just like
97588857acaSLaurent Vivier | `roundAndPackFloatx80' except that the input significand does not have to be
97688857acaSLaurent Vivier | normalized.
97788857acaSLaurent Vivier *----------------------------------------------------------------------------*/
97888857acaSLaurent Vivier 
97988857acaSLaurent Vivier floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision,
980c120391cSRichard Henderson                                        bool zSign, int32_t zExp,
98188857acaSLaurent Vivier                                        uint64_t zSig0, uint64_t zSig1,
98288857acaSLaurent Vivier                                        float_status *status);
98388857acaSLaurent Vivier 
98488857acaSLaurent Vivier /*----------------------------------------------------------------------------
9856b4c305cSPaolo Bonzini | The pattern for a default generated extended double-precision NaN.
9866b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
987af39bc8cSAleksandar Markovic floatx80 floatx80_default_nan(float_status *status);
9886b4c305cSPaolo Bonzini 
9896b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
9906b4c305cSPaolo Bonzini | Software IEC/IEEE quadruple-precision conversion routines.
9916b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
992f4014512SPeter Maydell int32_t float128_to_int32(float128, float_status *status);
993f4014512SPeter Maydell int32_t float128_to_int32_round_to_zero(float128, float_status *status);
994f42c2224SPeter Maydell int64_t float128_to_int64(float128, float_status *status);
995f42c2224SPeter Maydell int64_t float128_to_int64_round_to_zero(float128, float_status *status);
9962e6d8568SBharata B Rao uint64_t float128_to_uint64(float128, float_status *status);
9972e6d8568SBharata B Rao uint64_t float128_to_uint64_round_to_zero(float128, float_status *status);
998e45de992SDavid Hildenbrand uint32_t float128_to_uint32(float128, float_status *status);
999fd425037SBharata B Rao uint32_t float128_to_uint32_round_to_zero(float128, float_status *status);
1000e5a41ffaSPeter Maydell float32 float128_to_float32(float128, float_status *status);
1001e5a41ffaSPeter Maydell float64 float128_to_float64(float128, float_status *status);
1002e5a41ffaSPeter Maydell floatx80 float128_to_floatx80(float128, float_status *status);
10036b4c305cSPaolo Bonzini 
10046b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
10056b4c305cSPaolo Bonzini | Software IEC/IEEE quadruple-precision operations.
10066b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1007e5a41ffaSPeter Maydell float128 float128_round_to_int(float128, float_status *status);
1008e5a41ffaSPeter Maydell float128 float128_add(float128, float128, float_status *status);
1009e5a41ffaSPeter Maydell float128 float128_sub(float128, float128, float_status *status);
1010e5a41ffaSPeter Maydell float128 float128_mul(float128, float128, float_status *status);
1011e5a41ffaSPeter Maydell float128 float128_div(float128, float128, float_status *status);
1012e5a41ffaSPeter Maydell float128 float128_rem(float128, float128, float_status *status);
1013e5a41ffaSPeter Maydell float128 float128_sqrt(float128, float_status *status);
101471bfd65cSRichard Henderson FloatRelation float128_compare(float128, float128, float_status *status);
101571bfd65cSRichard Henderson FloatRelation float128_compare_quiet(float128, float128, float_status *status);
1016150c7a91SRichard Henderson bool float128_is_quiet_nan(float128, float_status *status);
1017150c7a91SRichard Henderson bool float128_is_signaling_nan(float128, float_status *status);
1018d619bb98SRichard Henderson float128 float128_silence_nan(float128, float_status *status);
1019e5a41ffaSPeter Maydell float128 float128_scalbn(float128, int, float_status *status);
10206b4c305cSPaolo Bonzini 
1021a49db98dSLuiz Capitulino static inline float128 float128_abs(float128 a)
10226b4c305cSPaolo Bonzini {
10236b4c305cSPaolo Bonzini     a.high &= 0x7fffffffffffffffLL;
10246b4c305cSPaolo Bonzini     return a;
10256b4c305cSPaolo Bonzini }
10266b4c305cSPaolo Bonzini 
1027a49db98dSLuiz Capitulino static inline float128 float128_chs(float128 a)
10286b4c305cSPaolo Bonzini {
10296b4c305cSPaolo Bonzini     a.high ^= 0x8000000000000000LL;
10306b4c305cSPaolo Bonzini     return a;
10316b4c305cSPaolo Bonzini }
10326b4c305cSPaolo Bonzini 
1033150c7a91SRichard Henderson static inline bool float128_is_infinity(float128 a)
10346b4c305cSPaolo Bonzini {
10356b4c305cSPaolo Bonzini     return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0;
10366b4c305cSPaolo Bonzini }
10376b4c305cSPaolo Bonzini 
1038150c7a91SRichard Henderson static inline bool float128_is_neg(float128 a)
10396b4c305cSPaolo Bonzini {
10406b4c305cSPaolo Bonzini     return a.high >> 63;
10416b4c305cSPaolo Bonzini }
10426b4c305cSPaolo Bonzini 
1043150c7a91SRichard Henderson static inline bool float128_is_zero(float128 a)
10446b4c305cSPaolo Bonzini {
10456b4c305cSPaolo Bonzini     return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
10466b4c305cSPaolo Bonzini }
10476b4c305cSPaolo Bonzini 
1048150c7a91SRichard Henderson static inline bool float128_is_zero_or_denormal(float128 a)
10496b4c305cSPaolo Bonzini {
10506b4c305cSPaolo Bonzini     return (a.high & 0x7fff000000000000LL) == 0;
10516b4c305cSPaolo Bonzini }
10526b4c305cSPaolo Bonzini 
105347393181SDavid Hildenbrand static inline bool float128_is_normal(float128 a)
105447393181SDavid Hildenbrand {
105547393181SDavid Hildenbrand     return (((a.high >> 48) + 1) & 0x7fff) >= 2;
105647393181SDavid Hildenbrand }
105747393181SDavid Hildenbrand 
105847393181SDavid Hildenbrand static inline bool float128_is_denormal(float128 a)
105947393181SDavid Hildenbrand {
106047393181SDavid Hildenbrand     return float128_is_zero_or_denormal(a) && !float128_is_zero(a);
106147393181SDavid Hildenbrand }
106247393181SDavid Hildenbrand 
1063150c7a91SRichard Henderson static inline bool float128_is_any_nan(float128 a)
10646b4c305cSPaolo Bonzini {
10656b4c305cSPaolo Bonzini     return ((a.high >> 48) & 0x7fff) == 0x7fff &&
10666b4c305cSPaolo Bonzini         ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0));
10676b4c305cSPaolo Bonzini }
10686b4c305cSPaolo Bonzini 
1069b7b1ac68SRichard Henderson static inline bool float128_eq(float128 a, float128 b, float_status *s)
1070b7b1ac68SRichard Henderson {
1071b7b1ac68SRichard Henderson     return float128_compare(a, b, s) == float_relation_equal;
1072b7b1ac68SRichard Henderson }
1073b7b1ac68SRichard Henderson 
1074b7b1ac68SRichard Henderson static inline bool float128_le(float128 a, float128 b, float_status *s)
1075b7b1ac68SRichard Henderson {
1076b7b1ac68SRichard Henderson     return float128_compare(a, b, s) <= float_relation_equal;
1077b7b1ac68SRichard Henderson }
1078b7b1ac68SRichard Henderson 
1079b7b1ac68SRichard Henderson static inline bool float128_lt(float128 a, float128 b, float_status *s)
1080b7b1ac68SRichard Henderson {
1081b7b1ac68SRichard Henderson     return float128_compare(a, b, s) < float_relation_equal;
1082b7b1ac68SRichard Henderson }
1083b7b1ac68SRichard Henderson 
1084b7b1ac68SRichard Henderson static inline bool float128_unordered(float128 a, float128 b, float_status *s)
1085b7b1ac68SRichard Henderson {
1086b7b1ac68SRichard Henderson     return float128_compare(a, b, s) == float_relation_unordered;
1087b7b1ac68SRichard Henderson }
1088b7b1ac68SRichard Henderson 
1089b7b1ac68SRichard Henderson static inline bool float128_eq_quiet(float128 a, float128 b, float_status *s)
1090b7b1ac68SRichard Henderson {
1091b7b1ac68SRichard Henderson     return float128_compare_quiet(a, b, s) == float_relation_equal;
1092b7b1ac68SRichard Henderson }
1093b7b1ac68SRichard Henderson 
1094b7b1ac68SRichard Henderson static inline bool float128_le_quiet(float128 a, float128 b, float_status *s)
1095b7b1ac68SRichard Henderson {
1096b7b1ac68SRichard Henderson     return float128_compare_quiet(a, b, s) <= float_relation_equal;
1097b7b1ac68SRichard Henderson }
1098b7b1ac68SRichard Henderson 
1099b7b1ac68SRichard Henderson static inline bool float128_lt_quiet(float128 a, float128 b, float_status *s)
1100b7b1ac68SRichard Henderson {
1101b7b1ac68SRichard Henderson     return float128_compare_quiet(a, b, s) < float_relation_equal;
1102b7b1ac68SRichard Henderson }
1103b7b1ac68SRichard Henderson 
1104b7b1ac68SRichard Henderson static inline bool float128_unordered_quiet(float128 a, float128 b,
1105b7b1ac68SRichard Henderson                                            float_status *s)
1106b7b1ac68SRichard Henderson {
1107b7b1ac68SRichard Henderson     return float128_compare_quiet(a, b, s) == float_relation_unordered;
1108b7b1ac68SRichard Henderson }
1109b7b1ac68SRichard Henderson 
11101e397eadSRichard Henderson #define float128_zero make_float128(0, 0)
11111e397eadSRichard Henderson 
11126b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
11136b4c305cSPaolo Bonzini | The pattern for a default generated quadruple-precision NaN.
11146b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1115af39bc8cSAleksandar Markovic float128 float128_default_nan(float_status *status);
11166b4c305cSPaolo Bonzini 
1117175de524SMarkus Armbruster #endif /* SOFTFLOAT_H */
1118