xref: /openbmc/qemu/include/fpu/softfloat.h (revision d1eb8f2acba579830cf3798c3c15ce51be852c56)
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 #if defined(CONFIG_SOLARIS) && defined(CONFIG_NEEDS_LIBSUNMATH)
866b4c305cSPaolo Bonzini #include <sunmath.h>
876b4c305cSPaolo Bonzini #endif
886b4c305cSPaolo Bonzini 
896b4c305cSPaolo Bonzini 
90d341d9f3SPeter Maydell /* This 'flag' type must be able to hold at least 0 and 1. It should
91d341d9f3SPeter Maydell  * probably be replaced with 'bool' but the uses would need to be audited
92d341d9f3SPeter Maydell  * to check that they weren't accidentally relying on it being a larger type.
93d341d9f3SPeter Maydell  */
946b4c305cSPaolo Bonzini typedef uint8_t flag;
956b4c305cSPaolo Bonzini 
966b4c305cSPaolo Bonzini #define LIT64( a ) a##LL
976b4c305cSPaolo Bonzini 
986b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
996b4c305cSPaolo Bonzini | Software IEC/IEEE floating-point ordering relations
1006b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1016b4c305cSPaolo Bonzini enum {
1026b4c305cSPaolo Bonzini     float_relation_less      = -1,
1036b4c305cSPaolo Bonzini     float_relation_equal     =  0,
1046b4c305cSPaolo Bonzini     float_relation_greater   =  1,
1056b4c305cSPaolo Bonzini     float_relation_unordered =  2
1066b4c305cSPaolo Bonzini };
1076b4c305cSPaolo Bonzini 
1086b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1096b4c305cSPaolo Bonzini | Software IEC/IEEE floating-point types.
1106b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1116b4c305cSPaolo Bonzini /* Use structures for soft-float types.  This prevents accidentally mixing
1126b4c305cSPaolo Bonzini    them with native int/float types.  A sufficiently clever compiler and
1136b4c305cSPaolo Bonzini    sane ABI should be able to see though these structs.  However
1146b4c305cSPaolo Bonzini    x86/gcc 3.x seems to struggle a bit, so leave them disabled by default.  */
1156b4c305cSPaolo Bonzini //#define USE_SOFTFLOAT_STRUCT_TYPES
1166b4c305cSPaolo Bonzini #ifdef USE_SOFTFLOAT_STRUCT_TYPES
1176b4c305cSPaolo Bonzini typedef struct {
1186b4c305cSPaolo Bonzini     uint16_t v;
1196b4c305cSPaolo Bonzini } float16;
1206b4c305cSPaolo Bonzini #define float16_val(x) (((float16)(x)).v)
1216b4c305cSPaolo Bonzini #define make_float16(x) __extension__ ({ float16 f16_val = {x}; f16_val; })
1226b4c305cSPaolo Bonzini #define const_float16(x) { x }
1236b4c305cSPaolo Bonzini typedef struct {
1246b4c305cSPaolo Bonzini     uint32_t v;
1256b4c305cSPaolo Bonzini } float32;
1266b4c305cSPaolo Bonzini /* The cast ensures an error if the wrong type is passed.  */
1276b4c305cSPaolo Bonzini #define float32_val(x) (((float32)(x)).v)
1286b4c305cSPaolo Bonzini #define make_float32(x) __extension__ ({ float32 f32_val = {x}; f32_val; })
1296b4c305cSPaolo Bonzini #define const_float32(x) { x }
1306b4c305cSPaolo Bonzini typedef struct {
1316b4c305cSPaolo Bonzini     uint64_t v;
1326b4c305cSPaolo Bonzini } float64;
1336b4c305cSPaolo Bonzini #define float64_val(x) (((float64)(x)).v)
1346b4c305cSPaolo Bonzini #define make_float64(x) __extension__ ({ float64 f64_val = {x}; f64_val; })
1356b4c305cSPaolo Bonzini #define const_float64(x) { x }
1366b4c305cSPaolo Bonzini #else
1376b4c305cSPaolo Bonzini typedef uint16_t float16;
1386b4c305cSPaolo Bonzini typedef uint32_t float32;
1396b4c305cSPaolo Bonzini typedef uint64_t float64;
1406b4c305cSPaolo Bonzini #define float16_val(x) (x)
1416b4c305cSPaolo Bonzini #define float32_val(x) (x)
1426b4c305cSPaolo Bonzini #define float64_val(x) (x)
1436b4c305cSPaolo Bonzini #define make_float16(x) (x)
1446b4c305cSPaolo Bonzini #define make_float32(x) (x)
1456b4c305cSPaolo Bonzini #define make_float64(x) (x)
1466b4c305cSPaolo Bonzini #define const_float16(x) (x)
1476b4c305cSPaolo Bonzini #define const_float32(x) (x)
1486b4c305cSPaolo Bonzini #define const_float64(x) (x)
1496b4c305cSPaolo Bonzini #endif
1506b4c305cSPaolo Bonzini typedef struct {
1516b4c305cSPaolo Bonzini     uint64_t low;
1526b4c305cSPaolo Bonzini     uint16_t high;
1536b4c305cSPaolo Bonzini } floatx80;
1546b4c305cSPaolo Bonzini #define make_floatx80(exp, mant) ((floatx80) { mant, exp })
1556b4c305cSPaolo Bonzini #define make_floatx80_init(exp, mant) { .low = mant, .high = exp }
1566b4c305cSPaolo Bonzini typedef struct {
1576b4c305cSPaolo Bonzini #ifdef HOST_WORDS_BIGENDIAN
1586b4c305cSPaolo Bonzini     uint64_t high, low;
1596b4c305cSPaolo Bonzini #else
1606b4c305cSPaolo Bonzini     uint64_t low, high;
1616b4c305cSPaolo Bonzini #endif
1626b4c305cSPaolo Bonzini } float128;
1636b4c305cSPaolo Bonzini #define make_float128(high_, low_) ((float128) { .high = high_, .low = low_ })
1646b4c305cSPaolo Bonzini #define make_float128_init(high_, low_) { .high = high_, .low = low_ }
1656b4c305cSPaolo Bonzini 
1666b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1676b4c305cSPaolo Bonzini | Software IEC/IEEE floating-point underflow tininess-detection mode.
1686b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1696b4c305cSPaolo Bonzini enum {
1706b4c305cSPaolo Bonzini     float_tininess_after_rounding  = 0,
1716b4c305cSPaolo Bonzini     float_tininess_before_rounding = 1
1726b4c305cSPaolo Bonzini };
1736b4c305cSPaolo Bonzini 
1746b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1756b4c305cSPaolo Bonzini | Software IEC/IEEE floating-point rounding mode.
1766b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1776b4c305cSPaolo Bonzini enum {
1786b4c305cSPaolo Bonzini     float_round_nearest_even = 0,
1796b4c305cSPaolo Bonzini     float_round_down         = 1,
1806b4c305cSPaolo Bonzini     float_round_up           = 2,
181f9288a76SPeter Maydell     float_round_to_zero      = 3,
182f9288a76SPeter Maydell     float_round_ties_away    = 4,
1836b4c305cSPaolo Bonzini };
1846b4c305cSPaolo Bonzini 
1856b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1866b4c305cSPaolo Bonzini | Software IEC/IEEE floating-point exception flags.
1876b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1886b4c305cSPaolo Bonzini enum {
1896b4c305cSPaolo Bonzini     float_flag_invalid   =  1,
1906b4c305cSPaolo Bonzini     float_flag_divbyzero =  4,
1916b4c305cSPaolo Bonzini     float_flag_overflow  =  8,
1926b4c305cSPaolo Bonzini     float_flag_underflow = 16,
1936b4c305cSPaolo Bonzini     float_flag_inexact   = 32,
1946b4c305cSPaolo Bonzini     float_flag_input_denormal = 64,
1956b4c305cSPaolo Bonzini     float_flag_output_denormal = 128
1966b4c305cSPaolo Bonzini };
1976b4c305cSPaolo Bonzini 
1986b4c305cSPaolo Bonzini typedef struct float_status {
1996b4c305cSPaolo Bonzini     signed char float_detect_tininess;
2006b4c305cSPaolo Bonzini     signed char float_rounding_mode;
201dfd60767SPranith Kumar     uint8_t     float_exception_flags;
2026b4c305cSPaolo Bonzini     signed char floatx80_rounding_precision;
2036b4c305cSPaolo Bonzini     /* should denormalised results go to zero and set the inexact flag? */
2046b4c305cSPaolo Bonzini     flag flush_to_zero;
2056b4c305cSPaolo Bonzini     /* should denormalised inputs go to zero and set the input_denormal flag? */
2066b4c305cSPaolo Bonzini     flag flush_inputs_to_zero;
2076b4c305cSPaolo Bonzini     flag default_nan_mode;
208af39bc8cSAleksandar Markovic     flag snan_bit_is_one;
2096b4c305cSPaolo Bonzini } float_status;
2106b4c305cSPaolo Bonzini 
211e5a41ffaSPeter Maydell static inline void set_float_detect_tininess(int val, float_status *status)
2126b4c305cSPaolo Bonzini {
213a2f2d288SPeter Maydell     status->float_detect_tininess = val;
2146b4c305cSPaolo Bonzini }
215e5a41ffaSPeter Maydell static inline void set_float_rounding_mode(int val, float_status *status)
216879d096bSPeter Maydell {
217a2f2d288SPeter Maydell     status->float_rounding_mode = val;
218879d096bSPeter Maydell }
219e5a41ffaSPeter Maydell static inline void set_float_exception_flags(int val, float_status *status)
220879d096bSPeter Maydell {
221a2f2d288SPeter Maydell     status->float_exception_flags = val;
222879d096bSPeter Maydell }
223e5a41ffaSPeter Maydell static inline void set_floatx80_rounding_precision(int val,
224e5a41ffaSPeter Maydell                                                    float_status *status)
225879d096bSPeter Maydell {
226a2f2d288SPeter Maydell     status->floatx80_rounding_precision = val;
227879d096bSPeter Maydell }
228e5a41ffaSPeter Maydell static inline void set_flush_to_zero(flag val, float_status *status)
2296b4c305cSPaolo Bonzini {
230a2f2d288SPeter Maydell     status->flush_to_zero = val;
2316b4c305cSPaolo Bonzini }
232e5a41ffaSPeter Maydell static inline void set_flush_inputs_to_zero(flag val, float_status *status)
2336b4c305cSPaolo Bonzini {
234a2f2d288SPeter Maydell     status->flush_inputs_to_zero = val;
2356b4c305cSPaolo Bonzini }
236e5a41ffaSPeter Maydell static inline void set_default_nan_mode(flag val, float_status *status)
2376b4c305cSPaolo Bonzini {
238a2f2d288SPeter Maydell     status->default_nan_mode = val;
2396b4c305cSPaolo Bonzini }
240af39bc8cSAleksandar Markovic static inline void set_snan_bit_is_one(flag val, float_status *status)
241af39bc8cSAleksandar Markovic {
242af39bc8cSAleksandar Markovic     status->snan_bit_is_one = val;
243af39bc8cSAleksandar Markovic }
244a49db98dSLuiz Capitulino static inline int get_float_detect_tininess(float_status *status)
245879d096bSPeter Maydell {
246a2f2d288SPeter Maydell     return status->float_detect_tininess;
247879d096bSPeter Maydell }
248a49db98dSLuiz Capitulino static inline int get_float_rounding_mode(float_status *status)
249879d096bSPeter Maydell {
250a2f2d288SPeter Maydell     return status->float_rounding_mode;
251879d096bSPeter Maydell }
252a49db98dSLuiz Capitulino static inline int get_float_exception_flags(float_status *status)
2536b4c305cSPaolo Bonzini {
254a2f2d288SPeter Maydell     return status->float_exception_flags;
2556b4c305cSPaolo Bonzini }
256a49db98dSLuiz Capitulino static inline int get_floatx80_rounding_precision(float_status *status)
257879d096bSPeter Maydell {
258a2f2d288SPeter Maydell     return status->floatx80_rounding_precision;
259879d096bSPeter Maydell }
260a49db98dSLuiz Capitulino static inline flag get_flush_to_zero(float_status *status)
261879d096bSPeter Maydell {
262a2f2d288SPeter Maydell     return status->flush_to_zero;
263879d096bSPeter Maydell }
264a49db98dSLuiz Capitulino static inline flag get_flush_inputs_to_zero(float_status *status)
265879d096bSPeter Maydell {
266a2f2d288SPeter Maydell     return status->flush_inputs_to_zero;
267879d096bSPeter Maydell }
268a49db98dSLuiz Capitulino static inline flag get_default_nan_mode(float_status *status)
269879d096bSPeter Maydell {
270a2f2d288SPeter Maydell     return status->default_nan_mode;
271879d096bSPeter Maydell }
2726b4c305cSPaolo Bonzini 
2736b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
2746b4c305cSPaolo Bonzini | Routine to raise any or all of the software IEC/IEEE floating-point
2756b4c305cSPaolo Bonzini | exception flags.
2766b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
277dfd60767SPranith Kumar void float_raise(uint8_t flags, float_status *status);
2786b4c305cSPaolo Bonzini 
2796b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
2807baeabceSAlex Bennée | If `a' is denormal and we are in flush-to-zero mode then set the
2817baeabceSAlex Bennée | input-denormal exception and return zero. Otherwise just return the value.
2827baeabceSAlex Bennée *----------------------------------------------------------------------------*/
283e5a41ffaSPeter Maydell float32 float32_squash_input_denormal(float32 a, float_status *status);
284e5a41ffaSPeter Maydell float64 float64_squash_input_denormal(float64 a, float_status *status);
2857baeabceSAlex Bennée 
2867baeabceSAlex Bennée /*----------------------------------------------------------------------------
2876b4c305cSPaolo Bonzini | Options to indicate which negations to perform in float*_muladd()
2886b4c305cSPaolo Bonzini | Using these differs from negating an input or output before calling
2896b4c305cSPaolo Bonzini | the muladd function in that this means that a NaN doesn't have its
2906b4c305cSPaolo Bonzini | sign bit inverted before it is propagated.
29167d43538SPeter Maydell | We also support halving the result before rounding, as a special
29267d43538SPeter Maydell | case to support the ARM fused-sqrt-step instruction FRSQRTS.
2936b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
2946b4c305cSPaolo Bonzini enum {
2956b4c305cSPaolo Bonzini     float_muladd_negate_c = 1,
2966b4c305cSPaolo Bonzini     float_muladd_negate_product = 2,
2976b4c305cSPaolo Bonzini     float_muladd_negate_result = 4,
29867d43538SPeter Maydell     float_muladd_halve_result = 8,
2996b4c305cSPaolo Bonzini };
3006b4c305cSPaolo Bonzini 
3016b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3026b4c305cSPaolo Bonzini | Software IEC/IEEE integer-to-floating-point conversion routines.
3036b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
304e5a41ffaSPeter Maydell float32 int32_to_float32(int32_t, float_status *status);
305e5a41ffaSPeter Maydell float64 int32_to_float64(int32_t, float_status *status);
306e5a41ffaSPeter Maydell float32 uint32_to_float32(uint32_t, float_status *status);
307e5a41ffaSPeter Maydell float64 uint32_to_float64(uint32_t, float_status *status);
308e5a41ffaSPeter Maydell floatx80 int32_to_floatx80(int32_t, float_status *status);
309e5a41ffaSPeter Maydell float128 int32_to_float128(int32_t, float_status *status);
310e5a41ffaSPeter Maydell float32 int64_to_float32(int64_t, float_status *status);
311e5a41ffaSPeter Maydell float64 int64_to_float64(int64_t, float_status *status);
312e5a41ffaSPeter Maydell floatx80 int64_to_floatx80(int64_t, float_status *status);
313e5a41ffaSPeter Maydell float128 int64_to_float128(int64_t, float_status *status);
314e5a41ffaSPeter Maydell float32 uint64_to_float32(uint64_t, float_status *status);
315e5a41ffaSPeter Maydell float64 uint64_to_float64(uint64_t, float_status *status);
316e5a41ffaSPeter Maydell float128 uint64_to_float128(uint64_t, float_status *status);
3176b4c305cSPaolo Bonzini 
3188afbdabaSPeter Maydell /* We provide the int16 versions for symmetry of API with float-to-int */
319e5a41ffaSPeter Maydell static inline float32 int16_to_float32(int16_t v, float_status *status)
3208afbdabaSPeter Maydell {
321ff32e16eSPeter Maydell     return int32_to_float32(v, status);
3228afbdabaSPeter Maydell }
3238afbdabaSPeter Maydell 
324e5a41ffaSPeter Maydell static inline float32 uint16_to_float32(uint16_t v, float_status *status)
3258afbdabaSPeter Maydell {
326ff32e16eSPeter Maydell     return uint32_to_float32(v, status);
3278afbdabaSPeter Maydell }
3288afbdabaSPeter Maydell 
329e5a41ffaSPeter Maydell static inline float64 int16_to_float64(int16_t v, float_status *status)
3308afbdabaSPeter Maydell {
331ff32e16eSPeter Maydell     return int32_to_float64(v, status);
3328afbdabaSPeter Maydell }
3338afbdabaSPeter Maydell 
334e5a41ffaSPeter Maydell static inline float64 uint16_to_float64(uint16_t v, float_status *status)
3358afbdabaSPeter Maydell {
336ff32e16eSPeter Maydell     return uint32_to_float64(v, status);
3378afbdabaSPeter Maydell }
3388afbdabaSPeter Maydell 
3396b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3406b4c305cSPaolo Bonzini | Software half-precision conversion routines.
3416b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
342e5a41ffaSPeter Maydell float16 float32_to_float16(float32, flag, float_status *status);
343e5a41ffaSPeter Maydell float32 float16_to_float32(float16, flag, float_status *status);
344e5a41ffaSPeter Maydell float16 float64_to_float16(float64 a, flag ieee, float_status *status);
345e5a41ffaSPeter Maydell float64 float16_to_float64(float16 a, flag ieee, float_status *status);
3466b4c305cSPaolo Bonzini 
3476b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3486b4c305cSPaolo Bonzini | Software half-precision operations.
3496b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
350af39bc8cSAleksandar Markovic int float16_is_quiet_nan(float16, float_status *status);
351af39bc8cSAleksandar Markovic int float16_is_signaling_nan(float16, float_status *status);
352af39bc8cSAleksandar Markovic float16 float16_maybe_silence_nan(float16, float_status *status);
3536b4c305cSPaolo Bonzini 
354a49db98dSLuiz Capitulino static inline int float16_is_any_nan(float16 a)
3556b4c305cSPaolo Bonzini {
3566b4c305cSPaolo Bonzini     return ((float16_val(a) & ~0x8000) > 0x7c00);
3576b4c305cSPaolo Bonzini }
3586b4c305cSPaolo Bonzini 
3596b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3606b4c305cSPaolo Bonzini | The pattern for a default generated half-precision NaN.
3616b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
362af39bc8cSAleksandar Markovic float16 float16_default_nan(float_status *status);
3636b4c305cSPaolo Bonzini 
3646b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3656b4c305cSPaolo Bonzini | Software IEC/IEEE single-precision conversion routines.
3666b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
3670bb721d7SPeter Maydell int16_t float32_to_int16(float32, float_status *status);
3680bb721d7SPeter Maydell uint16_t float32_to_uint16(float32, float_status *status);
3690bb721d7SPeter Maydell int16_t float32_to_int16_round_to_zero(float32, float_status *status);
3700bb721d7SPeter Maydell uint16_t float32_to_uint16_round_to_zero(float32, float_status *status);
371f4014512SPeter Maydell int32_t float32_to_int32(float32, float_status *status);
372f4014512SPeter Maydell int32_t float32_to_int32_round_to_zero(float32, float_status *status);
3733a87d009SPeter Maydell uint32_t float32_to_uint32(float32, float_status *status);
3743a87d009SPeter Maydell uint32_t float32_to_uint32_round_to_zero(float32, float_status *status);
375f42c2224SPeter Maydell int64_t float32_to_int64(float32, float_status *status);
376182f42fdSPeter Maydell uint64_t float32_to_uint64(float32, float_status *status);
377182f42fdSPeter Maydell uint64_t float32_to_uint64_round_to_zero(float32, float_status *status);
378f42c2224SPeter Maydell int64_t float32_to_int64_round_to_zero(float32, float_status *status);
379e5a41ffaSPeter Maydell float64 float32_to_float64(float32, float_status *status);
380e5a41ffaSPeter Maydell floatx80 float32_to_floatx80(float32, float_status *status);
381e5a41ffaSPeter Maydell float128 float32_to_float128(float32, float_status *status);
3826b4c305cSPaolo Bonzini 
3836b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3846b4c305cSPaolo Bonzini | Software IEC/IEEE single-precision operations.
3856b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
386e5a41ffaSPeter Maydell float32 float32_round_to_int(float32, float_status *status);
387e5a41ffaSPeter Maydell float32 float32_add(float32, float32, float_status *status);
388e5a41ffaSPeter Maydell float32 float32_sub(float32, float32, float_status *status);
389e5a41ffaSPeter Maydell float32 float32_mul(float32, float32, float_status *status);
390e5a41ffaSPeter Maydell float32 float32_div(float32, float32, float_status *status);
391e5a41ffaSPeter Maydell float32 float32_rem(float32, float32, float_status *status);
392e5a41ffaSPeter Maydell float32 float32_muladd(float32, float32, float32, int, float_status *status);
393e5a41ffaSPeter Maydell float32 float32_sqrt(float32, float_status *status);
394e5a41ffaSPeter Maydell float32 float32_exp2(float32, float_status *status);
395e5a41ffaSPeter Maydell float32 float32_log2(float32, float_status *status);
396e5a41ffaSPeter Maydell int float32_eq(float32, float32, float_status *status);
397e5a41ffaSPeter Maydell int float32_le(float32, float32, float_status *status);
398e5a41ffaSPeter Maydell int float32_lt(float32, float32, float_status *status);
399e5a41ffaSPeter Maydell int float32_unordered(float32, float32, float_status *status);
400e5a41ffaSPeter Maydell int float32_eq_quiet(float32, float32, float_status *status);
401e5a41ffaSPeter Maydell int float32_le_quiet(float32, float32, float_status *status);
402e5a41ffaSPeter Maydell int float32_lt_quiet(float32, float32, float_status *status);
403e5a41ffaSPeter Maydell int float32_unordered_quiet(float32, float32, float_status *status);
404e5a41ffaSPeter Maydell int float32_compare(float32, float32, float_status *status);
405e5a41ffaSPeter Maydell int float32_compare_quiet(float32, float32, float_status *status);
406e5a41ffaSPeter Maydell float32 float32_min(float32, float32, float_status *status);
407e5a41ffaSPeter Maydell float32 float32_max(float32, float32, float_status *status);
408e5a41ffaSPeter Maydell float32 float32_minnum(float32, float32, float_status *status);
409e5a41ffaSPeter Maydell float32 float32_maxnum(float32, float32, float_status *status);
410e5a41ffaSPeter Maydell float32 float32_minnummag(float32, float32, float_status *status);
411e5a41ffaSPeter Maydell float32 float32_maxnummag(float32, float32, float_status *status);
412af39bc8cSAleksandar Markovic int float32_is_quiet_nan(float32, float_status *status);
413af39bc8cSAleksandar Markovic int float32_is_signaling_nan(float32, float_status *status);
414af39bc8cSAleksandar Markovic float32 float32_maybe_silence_nan(float32, float_status *status);
415e5a41ffaSPeter Maydell float32 float32_scalbn(float32, int, float_status *status);
4166b4c305cSPaolo Bonzini 
417a49db98dSLuiz Capitulino static inline float32 float32_abs(float32 a)
4186b4c305cSPaolo Bonzini {
4196b4c305cSPaolo Bonzini     /* Note that abs does *not* handle NaN specially, nor does
4206b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
4216b4c305cSPaolo Bonzini      */
4226b4c305cSPaolo Bonzini     return make_float32(float32_val(a) & 0x7fffffff);
4236b4c305cSPaolo Bonzini }
4246b4c305cSPaolo Bonzini 
425a49db98dSLuiz Capitulino static inline float32 float32_chs(float32 a)
4266b4c305cSPaolo Bonzini {
4276b4c305cSPaolo Bonzini     /* Note that chs does *not* handle NaN specially, nor does
4286b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
4296b4c305cSPaolo Bonzini      */
4306b4c305cSPaolo Bonzini     return make_float32(float32_val(a) ^ 0x80000000);
4316b4c305cSPaolo Bonzini }
4326b4c305cSPaolo Bonzini 
433a49db98dSLuiz Capitulino static inline int float32_is_infinity(float32 a)
4346b4c305cSPaolo Bonzini {
4356b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7fffffff) == 0x7f800000;
4366b4c305cSPaolo Bonzini }
4376b4c305cSPaolo Bonzini 
438a49db98dSLuiz Capitulino static inline int float32_is_neg(float32 a)
4396b4c305cSPaolo Bonzini {
4406b4c305cSPaolo Bonzini     return float32_val(a) >> 31;
4416b4c305cSPaolo Bonzini }
4426b4c305cSPaolo Bonzini 
443a49db98dSLuiz Capitulino static inline int float32_is_zero(float32 a)
4446b4c305cSPaolo Bonzini {
4456b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7fffffff) == 0;
4466b4c305cSPaolo Bonzini }
4476b4c305cSPaolo Bonzini 
448a49db98dSLuiz Capitulino static inline int float32_is_any_nan(float32 a)
4496b4c305cSPaolo Bonzini {
4506b4c305cSPaolo Bonzini     return ((float32_val(a) & ~(1 << 31)) > 0x7f800000UL);
4516b4c305cSPaolo Bonzini }
4526b4c305cSPaolo Bonzini 
453a49db98dSLuiz Capitulino static inline int float32_is_zero_or_denormal(float32 a)
4546b4c305cSPaolo Bonzini {
4556b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7f800000) == 0;
4566b4c305cSPaolo Bonzini }
4576b4c305cSPaolo Bonzini 
458a49db98dSLuiz Capitulino static inline float32 float32_set_sign(float32 a, int sign)
4596b4c305cSPaolo Bonzini {
4606b4c305cSPaolo Bonzini     return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
4616b4c305cSPaolo Bonzini }
4626b4c305cSPaolo Bonzini 
4636b4c305cSPaolo Bonzini #define float32_zero make_float32(0)
4646b4c305cSPaolo Bonzini #define float32_one make_float32(0x3f800000)
4656b4c305cSPaolo Bonzini #define float32_ln2 make_float32(0x3f317218)
4666b4c305cSPaolo Bonzini #define float32_pi make_float32(0x40490fdb)
4676b4c305cSPaolo Bonzini #define float32_half make_float32(0x3f000000)
4686b4c305cSPaolo Bonzini #define float32_infinity make_float32(0x7f800000)
4696b4c305cSPaolo Bonzini 
4706b4c305cSPaolo Bonzini 
4716b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
4726b4c305cSPaolo Bonzini | The pattern for a default generated single-precision NaN.
4736b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
474af39bc8cSAleksandar Markovic float32 float32_default_nan(float_status *status);
4756b4c305cSPaolo Bonzini 
4766b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
4776b4c305cSPaolo Bonzini | Software IEC/IEEE double-precision conversion routines.
4786b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
4790bb721d7SPeter Maydell int16_t float64_to_int16(float64, float_status *status);
4800bb721d7SPeter Maydell uint16_t float64_to_uint16(float64, float_status *status);
4810bb721d7SPeter Maydell int16_t float64_to_int16_round_to_zero(float64, float_status *status);
4820bb721d7SPeter Maydell uint16_t float64_to_uint16_round_to_zero(float64, float_status *status);
483f4014512SPeter Maydell int32_t float64_to_int32(float64, float_status *status);
484f4014512SPeter Maydell int32_t float64_to_int32_round_to_zero(float64, float_status *status);
4853a87d009SPeter Maydell uint32_t float64_to_uint32(float64, float_status *status);
4863a87d009SPeter Maydell uint32_t float64_to_uint32_round_to_zero(float64, float_status *status);
487f42c2224SPeter Maydell int64_t float64_to_int64(float64, float_status *status);
488f42c2224SPeter Maydell int64_t float64_to_int64_round_to_zero(float64, float_status *status);
489182f42fdSPeter Maydell uint64_t float64_to_uint64(float64 a, float_status *status);
490182f42fdSPeter Maydell uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *status);
491e5a41ffaSPeter Maydell float32 float64_to_float32(float64, float_status *status);
492e5a41ffaSPeter Maydell floatx80 float64_to_floatx80(float64, float_status *status);
493e5a41ffaSPeter Maydell float128 float64_to_float128(float64, float_status *status);
4946b4c305cSPaolo Bonzini 
4956b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
4966b4c305cSPaolo Bonzini | Software IEC/IEEE double-precision operations.
4976b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
498e5a41ffaSPeter Maydell float64 float64_round_to_int(float64, float_status *status);
499e5a41ffaSPeter Maydell float64 float64_trunc_to_int(float64, float_status *status);
500e5a41ffaSPeter Maydell float64 float64_add(float64, float64, float_status *status);
501e5a41ffaSPeter Maydell float64 float64_sub(float64, float64, float_status *status);
502e5a41ffaSPeter Maydell float64 float64_mul(float64, float64, float_status *status);
503e5a41ffaSPeter Maydell float64 float64_div(float64, float64, float_status *status);
504e5a41ffaSPeter Maydell float64 float64_rem(float64, float64, float_status *status);
505e5a41ffaSPeter Maydell float64 float64_muladd(float64, float64, float64, int, float_status *status);
506e5a41ffaSPeter Maydell float64 float64_sqrt(float64, float_status *status);
507e5a41ffaSPeter Maydell float64 float64_log2(float64, float_status *status);
508e5a41ffaSPeter Maydell int float64_eq(float64, float64, float_status *status);
509e5a41ffaSPeter Maydell int float64_le(float64, float64, float_status *status);
510e5a41ffaSPeter Maydell int float64_lt(float64, float64, float_status *status);
511e5a41ffaSPeter Maydell int float64_unordered(float64, float64, float_status *status);
512e5a41ffaSPeter Maydell int float64_eq_quiet(float64, float64, float_status *status);
513e5a41ffaSPeter Maydell int float64_le_quiet(float64, float64, float_status *status);
514e5a41ffaSPeter Maydell int float64_lt_quiet(float64, float64, float_status *status);
515e5a41ffaSPeter Maydell int float64_unordered_quiet(float64, float64, float_status *status);
516e5a41ffaSPeter Maydell int float64_compare(float64, float64, float_status *status);
517e5a41ffaSPeter Maydell int float64_compare_quiet(float64, float64, float_status *status);
518e5a41ffaSPeter Maydell float64 float64_min(float64, float64, float_status *status);
519e5a41ffaSPeter Maydell float64 float64_max(float64, float64, float_status *status);
520e5a41ffaSPeter Maydell float64 float64_minnum(float64, float64, float_status *status);
521e5a41ffaSPeter Maydell float64 float64_maxnum(float64, float64, float_status *status);
522e5a41ffaSPeter Maydell float64 float64_minnummag(float64, float64, float_status *status);
523e5a41ffaSPeter Maydell float64 float64_maxnummag(float64, float64, float_status *status);
524af39bc8cSAleksandar Markovic int float64_is_quiet_nan(float64 a, float_status *status);
525af39bc8cSAleksandar Markovic int float64_is_signaling_nan(float64, float_status *status);
526af39bc8cSAleksandar Markovic float64 float64_maybe_silence_nan(float64, float_status *status);
527e5a41ffaSPeter Maydell float64 float64_scalbn(float64, int, float_status *status);
5286b4c305cSPaolo Bonzini 
529a49db98dSLuiz Capitulino static inline float64 float64_abs(float64 a)
5306b4c305cSPaolo Bonzini {
5316b4c305cSPaolo Bonzini     /* Note that abs does *not* handle NaN specially, nor does
5326b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
5336b4c305cSPaolo Bonzini      */
5346b4c305cSPaolo Bonzini     return make_float64(float64_val(a) & 0x7fffffffffffffffLL);
5356b4c305cSPaolo Bonzini }
5366b4c305cSPaolo Bonzini 
537a49db98dSLuiz Capitulino static inline float64 float64_chs(float64 a)
5386b4c305cSPaolo Bonzini {
5396b4c305cSPaolo Bonzini     /* Note that chs does *not* handle NaN specially, nor does
5406b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
5416b4c305cSPaolo Bonzini      */
5426b4c305cSPaolo Bonzini     return make_float64(float64_val(a) ^ 0x8000000000000000LL);
5436b4c305cSPaolo Bonzini }
5446b4c305cSPaolo Bonzini 
545a49db98dSLuiz Capitulino static inline int float64_is_infinity(float64 a)
5466b4c305cSPaolo Bonzini {
5476b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL;
5486b4c305cSPaolo Bonzini }
5496b4c305cSPaolo Bonzini 
550a49db98dSLuiz Capitulino static inline int float64_is_neg(float64 a)
5516b4c305cSPaolo Bonzini {
5526b4c305cSPaolo Bonzini     return float64_val(a) >> 63;
5536b4c305cSPaolo Bonzini }
5546b4c305cSPaolo Bonzini 
555a49db98dSLuiz Capitulino static inline int float64_is_zero(float64 a)
5566b4c305cSPaolo Bonzini {
5576b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7fffffffffffffffLL) == 0;
5586b4c305cSPaolo Bonzini }
5596b4c305cSPaolo Bonzini 
560a49db98dSLuiz Capitulino static inline int float64_is_any_nan(float64 a)
5616b4c305cSPaolo Bonzini {
5626b4c305cSPaolo Bonzini     return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL);
5636b4c305cSPaolo Bonzini }
5646b4c305cSPaolo Bonzini 
565a49db98dSLuiz Capitulino static inline int float64_is_zero_or_denormal(float64 a)
5666b4c305cSPaolo Bonzini {
5676b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7ff0000000000000LL) == 0;
5686b4c305cSPaolo Bonzini }
5696b4c305cSPaolo Bonzini 
570a49db98dSLuiz Capitulino static inline float64 float64_set_sign(float64 a, int sign)
5716b4c305cSPaolo Bonzini {
5726b4c305cSPaolo Bonzini     return make_float64((float64_val(a) & 0x7fffffffffffffffULL)
5736b4c305cSPaolo Bonzini                         | ((int64_t)sign << 63));
5746b4c305cSPaolo Bonzini }
5756b4c305cSPaolo Bonzini 
5766b4c305cSPaolo Bonzini #define float64_zero make_float64(0)
5776b4c305cSPaolo Bonzini #define float64_one make_float64(0x3ff0000000000000LL)
5786b4c305cSPaolo Bonzini #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
5796b4c305cSPaolo Bonzini #define float64_pi make_float64(0x400921fb54442d18LL)
5806b4c305cSPaolo Bonzini #define float64_half make_float64(0x3fe0000000000000LL)
5816b4c305cSPaolo Bonzini #define float64_infinity make_float64(0x7ff0000000000000LL)
5826b4c305cSPaolo Bonzini 
5836b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
5846b4c305cSPaolo Bonzini | The pattern for a default generated double-precision NaN.
5856b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
586af39bc8cSAleksandar Markovic float64 float64_default_nan(float_status *status);
5876b4c305cSPaolo Bonzini 
5886b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
5896b4c305cSPaolo Bonzini | Software IEC/IEEE extended double-precision conversion routines.
5906b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
591f4014512SPeter Maydell int32_t floatx80_to_int32(floatx80, float_status *status);
592f4014512SPeter Maydell int32_t floatx80_to_int32_round_to_zero(floatx80, float_status *status);
593f42c2224SPeter Maydell int64_t floatx80_to_int64(floatx80, float_status *status);
594f42c2224SPeter Maydell int64_t floatx80_to_int64_round_to_zero(floatx80, float_status *status);
595e5a41ffaSPeter Maydell float32 floatx80_to_float32(floatx80, float_status *status);
596e5a41ffaSPeter Maydell float64 floatx80_to_float64(floatx80, float_status *status);
597e5a41ffaSPeter Maydell float128 floatx80_to_float128(floatx80, float_status *status);
5986b4c305cSPaolo Bonzini 
5996b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
6006b4c305cSPaolo Bonzini | Software IEC/IEEE extended double-precision operations.
6016b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
602e5a41ffaSPeter Maydell floatx80 floatx80_round_to_int(floatx80, float_status *status);
603e5a41ffaSPeter Maydell floatx80 floatx80_add(floatx80, floatx80, float_status *status);
604e5a41ffaSPeter Maydell floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
605e5a41ffaSPeter Maydell floatx80 floatx80_mul(floatx80, floatx80, float_status *status);
606e5a41ffaSPeter Maydell floatx80 floatx80_div(floatx80, floatx80, float_status *status);
607e5a41ffaSPeter Maydell floatx80 floatx80_rem(floatx80, floatx80, float_status *status);
608e5a41ffaSPeter Maydell floatx80 floatx80_sqrt(floatx80, float_status *status);
609e5a41ffaSPeter Maydell int floatx80_eq(floatx80, floatx80, float_status *status);
610e5a41ffaSPeter Maydell int floatx80_le(floatx80, floatx80, float_status *status);
611e5a41ffaSPeter Maydell int floatx80_lt(floatx80, floatx80, float_status *status);
612e5a41ffaSPeter Maydell int floatx80_unordered(floatx80, floatx80, float_status *status);
613e5a41ffaSPeter Maydell int floatx80_eq_quiet(floatx80, floatx80, float_status *status);
614e5a41ffaSPeter Maydell int floatx80_le_quiet(floatx80, floatx80, float_status *status);
615e5a41ffaSPeter Maydell int floatx80_lt_quiet(floatx80, floatx80, float_status *status);
616e5a41ffaSPeter Maydell int floatx80_unordered_quiet(floatx80, floatx80, float_status *status);
617e5a41ffaSPeter Maydell int floatx80_compare(floatx80, floatx80, float_status *status);
618e5a41ffaSPeter Maydell int floatx80_compare_quiet(floatx80, floatx80, float_status *status);
619af39bc8cSAleksandar Markovic int floatx80_is_quiet_nan(floatx80, float_status *status);
620af39bc8cSAleksandar Markovic int floatx80_is_signaling_nan(floatx80, float_status *status);
621af39bc8cSAleksandar Markovic floatx80 floatx80_maybe_silence_nan(floatx80, float_status *status);
622e5a41ffaSPeter Maydell floatx80 floatx80_scalbn(floatx80, int, float_status *status);
6236b4c305cSPaolo Bonzini 
624a49db98dSLuiz Capitulino static inline floatx80 floatx80_abs(floatx80 a)
6256b4c305cSPaolo Bonzini {
6266b4c305cSPaolo Bonzini     a.high &= 0x7fff;
6276b4c305cSPaolo Bonzini     return a;
6286b4c305cSPaolo Bonzini }
6296b4c305cSPaolo Bonzini 
630a49db98dSLuiz Capitulino static inline floatx80 floatx80_chs(floatx80 a)
6316b4c305cSPaolo Bonzini {
6326b4c305cSPaolo Bonzini     a.high ^= 0x8000;
6336b4c305cSPaolo Bonzini     return a;
6346b4c305cSPaolo Bonzini }
6356b4c305cSPaolo Bonzini 
636a49db98dSLuiz Capitulino static inline int floatx80_is_infinity(floatx80 a)
6376b4c305cSPaolo Bonzini {
6386b4c305cSPaolo Bonzini     return (a.high & 0x7fff) == 0x7fff && a.low == 0x8000000000000000LL;
6396b4c305cSPaolo Bonzini }
6406b4c305cSPaolo Bonzini 
641a49db98dSLuiz Capitulino static inline int floatx80_is_neg(floatx80 a)
6426b4c305cSPaolo Bonzini {
6436b4c305cSPaolo Bonzini     return a.high >> 15;
6446b4c305cSPaolo Bonzini }
6456b4c305cSPaolo Bonzini 
646a49db98dSLuiz Capitulino static inline int floatx80_is_zero(floatx80 a)
6476b4c305cSPaolo Bonzini {
6486b4c305cSPaolo Bonzini     return (a.high & 0x7fff) == 0 && a.low == 0;
6496b4c305cSPaolo Bonzini }
6506b4c305cSPaolo Bonzini 
651a49db98dSLuiz Capitulino static inline int floatx80_is_zero_or_denormal(floatx80 a)
6526b4c305cSPaolo Bonzini {
6536b4c305cSPaolo Bonzini     return (a.high & 0x7fff) == 0;
6546b4c305cSPaolo Bonzini }
6556b4c305cSPaolo Bonzini 
656a49db98dSLuiz Capitulino static inline int floatx80_is_any_nan(floatx80 a)
6576b4c305cSPaolo Bonzini {
6586b4c305cSPaolo Bonzini     return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
6596b4c305cSPaolo Bonzini }
6606b4c305cSPaolo Bonzini 
661*d1eb8f2aSAndrew Dutcher /*----------------------------------------------------------------------------
662*d1eb8f2aSAndrew Dutcher | Return whether the given value is an invalid floatx80 encoding.
663*d1eb8f2aSAndrew Dutcher | Invalid floatx80 encodings arise when the integer bit is not set, but
664*d1eb8f2aSAndrew Dutcher | the exponent is not zero. The only times the integer bit is permitted to
665*d1eb8f2aSAndrew Dutcher | be zero is in subnormal numbers and the value zero.
666*d1eb8f2aSAndrew Dutcher | This includes what the Intel software developer's manual calls pseudo-NaNs,
667*d1eb8f2aSAndrew Dutcher | pseudo-infinities and un-normal numbers. It does not include
668*d1eb8f2aSAndrew Dutcher | pseudo-denormals, which must still be correctly handled as inputs even
669*d1eb8f2aSAndrew Dutcher | if they are never generated as outputs.
670*d1eb8f2aSAndrew Dutcher *----------------------------------------------------------------------------*/
671*d1eb8f2aSAndrew Dutcher static inline bool floatx80_invalid_encoding(floatx80 a)
672*d1eb8f2aSAndrew Dutcher {
673*d1eb8f2aSAndrew Dutcher     return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0;
674*d1eb8f2aSAndrew Dutcher }
675*d1eb8f2aSAndrew Dutcher 
6766b4c305cSPaolo Bonzini #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
6776b4c305cSPaolo Bonzini #define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
6786b4c305cSPaolo Bonzini #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
6796b4c305cSPaolo Bonzini #define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
6806b4c305cSPaolo Bonzini #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
6816b4c305cSPaolo Bonzini #define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
6826b4c305cSPaolo Bonzini 
6836b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
6846b4c305cSPaolo Bonzini | The pattern for a default generated extended double-precision NaN.
6856b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
686af39bc8cSAleksandar Markovic floatx80 floatx80_default_nan(float_status *status);
6876b4c305cSPaolo Bonzini 
6886b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
6896b4c305cSPaolo Bonzini | Software IEC/IEEE quadruple-precision conversion routines.
6906b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
691f4014512SPeter Maydell int32_t float128_to_int32(float128, float_status *status);
692f4014512SPeter Maydell int32_t float128_to_int32_round_to_zero(float128, float_status *status);
693f42c2224SPeter Maydell int64_t float128_to_int64(float128, float_status *status);
694f42c2224SPeter Maydell int64_t float128_to_int64_round_to_zero(float128, float_status *status);
695e5a41ffaSPeter Maydell float32 float128_to_float32(float128, float_status *status);
696e5a41ffaSPeter Maydell float64 float128_to_float64(float128, float_status *status);
697e5a41ffaSPeter Maydell floatx80 float128_to_floatx80(float128, float_status *status);
6986b4c305cSPaolo Bonzini 
6996b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
7006b4c305cSPaolo Bonzini | Software IEC/IEEE quadruple-precision operations.
7016b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
702e5a41ffaSPeter Maydell float128 float128_round_to_int(float128, float_status *status);
703e5a41ffaSPeter Maydell float128 float128_add(float128, float128, float_status *status);
704e5a41ffaSPeter Maydell float128 float128_sub(float128, float128, float_status *status);
705e5a41ffaSPeter Maydell float128 float128_mul(float128, float128, float_status *status);
706e5a41ffaSPeter Maydell float128 float128_div(float128, float128, float_status *status);
707e5a41ffaSPeter Maydell float128 float128_rem(float128, float128, float_status *status);
708e5a41ffaSPeter Maydell float128 float128_sqrt(float128, float_status *status);
709e5a41ffaSPeter Maydell int float128_eq(float128, float128, float_status *status);
710e5a41ffaSPeter Maydell int float128_le(float128, float128, float_status *status);
711e5a41ffaSPeter Maydell int float128_lt(float128, float128, float_status *status);
712e5a41ffaSPeter Maydell int float128_unordered(float128, float128, float_status *status);
713e5a41ffaSPeter Maydell int float128_eq_quiet(float128, float128, float_status *status);
714e5a41ffaSPeter Maydell int float128_le_quiet(float128, float128, float_status *status);
715e5a41ffaSPeter Maydell int float128_lt_quiet(float128, float128, float_status *status);
716e5a41ffaSPeter Maydell int float128_unordered_quiet(float128, float128, float_status *status);
717e5a41ffaSPeter Maydell int float128_compare(float128, float128, float_status *status);
718e5a41ffaSPeter Maydell int float128_compare_quiet(float128, float128, float_status *status);
719af39bc8cSAleksandar Markovic int float128_is_quiet_nan(float128, float_status *status);
720af39bc8cSAleksandar Markovic int float128_is_signaling_nan(float128, float_status *status);
721af39bc8cSAleksandar Markovic float128 float128_maybe_silence_nan(float128, float_status *status);
722e5a41ffaSPeter Maydell float128 float128_scalbn(float128, int, float_status *status);
7236b4c305cSPaolo Bonzini 
724a49db98dSLuiz Capitulino static inline float128 float128_abs(float128 a)
7256b4c305cSPaolo Bonzini {
7266b4c305cSPaolo Bonzini     a.high &= 0x7fffffffffffffffLL;
7276b4c305cSPaolo Bonzini     return a;
7286b4c305cSPaolo Bonzini }
7296b4c305cSPaolo Bonzini 
730a49db98dSLuiz Capitulino static inline float128 float128_chs(float128 a)
7316b4c305cSPaolo Bonzini {
7326b4c305cSPaolo Bonzini     a.high ^= 0x8000000000000000LL;
7336b4c305cSPaolo Bonzini     return a;
7346b4c305cSPaolo Bonzini }
7356b4c305cSPaolo Bonzini 
736a49db98dSLuiz Capitulino static inline int float128_is_infinity(float128 a)
7376b4c305cSPaolo Bonzini {
7386b4c305cSPaolo Bonzini     return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0;
7396b4c305cSPaolo Bonzini }
7406b4c305cSPaolo Bonzini 
741a49db98dSLuiz Capitulino static inline int float128_is_neg(float128 a)
7426b4c305cSPaolo Bonzini {
7436b4c305cSPaolo Bonzini     return a.high >> 63;
7446b4c305cSPaolo Bonzini }
7456b4c305cSPaolo Bonzini 
746a49db98dSLuiz Capitulino static inline int float128_is_zero(float128 a)
7476b4c305cSPaolo Bonzini {
7486b4c305cSPaolo Bonzini     return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
7496b4c305cSPaolo Bonzini }
7506b4c305cSPaolo Bonzini 
751a49db98dSLuiz Capitulino static inline int float128_is_zero_or_denormal(float128 a)
7526b4c305cSPaolo Bonzini {
7536b4c305cSPaolo Bonzini     return (a.high & 0x7fff000000000000LL) == 0;
7546b4c305cSPaolo Bonzini }
7556b4c305cSPaolo Bonzini 
756a49db98dSLuiz Capitulino static inline int float128_is_any_nan(float128 a)
7576b4c305cSPaolo Bonzini {
7586b4c305cSPaolo Bonzini     return ((a.high >> 48) & 0x7fff) == 0x7fff &&
7596b4c305cSPaolo Bonzini         ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0));
7606b4c305cSPaolo Bonzini }
7616b4c305cSPaolo Bonzini 
7621e397eadSRichard Henderson #define float128_zero make_float128(0, 0)
7631e397eadSRichard Henderson 
7646b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
7656b4c305cSPaolo Bonzini | The pattern for a default generated quadruple-precision NaN.
7666b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
767af39bc8cSAleksandar Markovic float128 float128_default_nan(float_status *status);
7686b4c305cSPaolo Bonzini 
769175de524SMarkus Armbruster #endif /* SOFTFLOAT_H */
770