xref: /qemu/include/fpu/softfloat.h (revision 588e6dfd)
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 #define LIT64( a ) a##LL
866b4c305cSPaolo Bonzini 
876b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
886b4c305cSPaolo Bonzini | Software IEC/IEEE floating-point ordering relations
896b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
906b4c305cSPaolo Bonzini enum {
916b4c305cSPaolo Bonzini     float_relation_less      = -1,
926b4c305cSPaolo Bonzini     float_relation_equal     =  0,
936b4c305cSPaolo Bonzini     float_relation_greater   =  1,
946b4c305cSPaolo Bonzini     float_relation_unordered =  2
956b4c305cSPaolo Bonzini };
966b4c305cSPaolo Bonzini 
97cfd88fc6SAlex Bennée #include "fpu/softfloat-types.h"
986b4c305cSPaolo Bonzini 
99e5a41ffaSPeter Maydell static inline void set_float_detect_tininess(int val, float_status *status)
1006b4c305cSPaolo Bonzini {
101a2f2d288SPeter Maydell     status->float_detect_tininess = val;
1026b4c305cSPaolo Bonzini }
103e5a41ffaSPeter Maydell static inline void set_float_rounding_mode(int val, float_status *status)
104879d096bSPeter Maydell {
105a2f2d288SPeter Maydell     status->float_rounding_mode = val;
106879d096bSPeter Maydell }
107e5a41ffaSPeter Maydell static inline void set_float_exception_flags(int val, float_status *status)
108879d096bSPeter Maydell {
109a2f2d288SPeter Maydell     status->float_exception_flags = val;
110879d096bSPeter Maydell }
111e5a41ffaSPeter Maydell static inline void set_floatx80_rounding_precision(int val,
112e5a41ffaSPeter Maydell                                                    float_status *status)
113879d096bSPeter Maydell {
114a2f2d288SPeter Maydell     status->floatx80_rounding_precision = val;
115879d096bSPeter Maydell }
116e5a41ffaSPeter Maydell static inline void set_flush_to_zero(flag val, float_status *status)
1176b4c305cSPaolo Bonzini {
118a2f2d288SPeter Maydell     status->flush_to_zero = val;
1196b4c305cSPaolo Bonzini }
120e5a41ffaSPeter Maydell static inline void set_flush_inputs_to_zero(flag val, float_status *status)
1216b4c305cSPaolo Bonzini {
122a2f2d288SPeter Maydell     status->flush_inputs_to_zero = val;
1236b4c305cSPaolo Bonzini }
124e5a41ffaSPeter Maydell static inline void set_default_nan_mode(flag val, float_status *status)
1256b4c305cSPaolo Bonzini {
126a2f2d288SPeter Maydell     status->default_nan_mode = val;
1276b4c305cSPaolo Bonzini }
128af39bc8cSAleksandar Markovic static inline void set_snan_bit_is_one(flag val, float_status *status)
129af39bc8cSAleksandar Markovic {
130af39bc8cSAleksandar Markovic     status->snan_bit_is_one = val;
131af39bc8cSAleksandar Markovic }
132a49db98dSLuiz Capitulino static inline int get_float_detect_tininess(float_status *status)
133879d096bSPeter Maydell {
134a2f2d288SPeter Maydell     return status->float_detect_tininess;
135879d096bSPeter Maydell }
136a49db98dSLuiz Capitulino static inline int get_float_rounding_mode(float_status *status)
137879d096bSPeter Maydell {
138a2f2d288SPeter Maydell     return status->float_rounding_mode;
139879d096bSPeter Maydell }
140a49db98dSLuiz Capitulino static inline int get_float_exception_flags(float_status *status)
1416b4c305cSPaolo Bonzini {
142a2f2d288SPeter Maydell     return status->float_exception_flags;
1436b4c305cSPaolo Bonzini }
144a49db98dSLuiz Capitulino static inline int get_floatx80_rounding_precision(float_status *status)
145879d096bSPeter Maydell {
146a2f2d288SPeter Maydell     return status->floatx80_rounding_precision;
147879d096bSPeter Maydell }
148a49db98dSLuiz Capitulino static inline flag get_flush_to_zero(float_status *status)
149879d096bSPeter Maydell {
150a2f2d288SPeter Maydell     return status->flush_to_zero;
151879d096bSPeter Maydell }
152a49db98dSLuiz Capitulino static inline flag get_flush_inputs_to_zero(float_status *status)
153879d096bSPeter Maydell {
154a2f2d288SPeter Maydell     return status->flush_inputs_to_zero;
155879d096bSPeter Maydell }
156a49db98dSLuiz Capitulino static inline flag get_default_nan_mode(float_status *status)
157879d096bSPeter Maydell {
158a2f2d288SPeter Maydell     return status->default_nan_mode;
159879d096bSPeter Maydell }
1606b4c305cSPaolo Bonzini 
1616b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1626b4c305cSPaolo Bonzini | Routine to raise any or all of the software IEC/IEEE floating-point
1636b4c305cSPaolo Bonzini | exception flags.
1646b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
165dfd60767SPranith Kumar void float_raise(uint8_t flags, float_status *status);
1666b4c305cSPaolo Bonzini 
1676b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1687baeabceSAlex Bennée | If `a' is denormal and we are in flush-to-zero mode then set the
1697baeabceSAlex Bennée | input-denormal exception and return zero. Otherwise just return the value.
1707baeabceSAlex Bennée *----------------------------------------------------------------------------*/
171210cbd49SAlex Bennée float16 float16_squash_input_denormal(float16 a, float_status *status);
172e5a41ffaSPeter Maydell float32 float32_squash_input_denormal(float32 a, float_status *status);
173e5a41ffaSPeter Maydell float64 float64_squash_input_denormal(float64 a, float_status *status);
1747baeabceSAlex Bennée 
1757baeabceSAlex Bennée /*----------------------------------------------------------------------------
1766b4c305cSPaolo Bonzini | Options to indicate which negations to perform in float*_muladd()
1776b4c305cSPaolo Bonzini | Using these differs from negating an input or output before calling
1786b4c305cSPaolo Bonzini | the muladd function in that this means that a NaN doesn't have its
1796b4c305cSPaolo Bonzini | sign bit inverted before it is propagated.
18067d43538SPeter Maydell | We also support halving the result before rounding, as a special
18167d43538SPeter Maydell | case to support the ARM fused-sqrt-step instruction FRSQRTS.
1826b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1836b4c305cSPaolo Bonzini enum {
1846b4c305cSPaolo Bonzini     float_muladd_negate_c = 1,
1856b4c305cSPaolo Bonzini     float_muladd_negate_product = 2,
1866b4c305cSPaolo Bonzini     float_muladd_negate_result = 4,
18767d43538SPeter Maydell     float_muladd_halve_result = 8,
1886b4c305cSPaolo Bonzini };
1896b4c305cSPaolo Bonzini 
1906b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
1916b4c305cSPaolo Bonzini | Software IEC/IEEE integer-to-floating-point conversion routines.
1926b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
1932abdfe24SRichard Henderson 
1942abdfe24SRichard Henderson float16 int16_to_float16_scalbn(int16_t a, int, float_status *status);
1952abdfe24SRichard Henderson float16 int32_to_float16_scalbn(int32_t a, int, float_status *status);
1962abdfe24SRichard Henderson float16 int64_to_float16_scalbn(int64_t a, int, float_status *status);
1972abdfe24SRichard Henderson float16 uint16_to_float16_scalbn(uint16_t a, int, float_status *status);
1982abdfe24SRichard Henderson float16 uint32_to_float16_scalbn(uint32_t a, int, float_status *status);
1992abdfe24SRichard Henderson float16 uint64_to_float16_scalbn(uint64_t a, int, float_status *status);
2002abdfe24SRichard Henderson 
2012abdfe24SRichard Henderson float16 int16_to_float16(int16_t a, float_status *status);
2022abdfe24SRichard Henderson float16 int32_to_float16(int32_t a, float_status *status);
2032abdfe24SRichard Henderson float16 int64_to_float16(int64_t a, float_status *status);
2042abdfe24SRichard Henderson float16 uint16_to_float16(uint16_t a, float_status *status);
2052abdfe24SRichard Henderson float16 uint32_to_float16(uint32_t a, float_status *status);
2062abdfe24SRichard Henderson float16 uint64_to_float16(uint64_t a, float_status *status);
2072abdfe24SRichard Henderson 
2082abdfe24SRichard Henderson float32 int16_to_float32_scalbn(int16_t, int, float_status *status);
2092abdfe24SRichard Henderson float32 int32_to_float32_scalbn(int32_t, int, float_status *status);
2102abdfe24SRichard Henderson float32 int64_to_float32_scalbn(int64_t, int, float_status *status);
2112abdfe24SRichard Henderson float32 uint16_to_float32_scalbn(uint16_t, int, float_status *status);
2122abdfe24SRichard Henderson float32 uint32_to_float32_scalbn(uint32_t, int, float_status *status);
2132abdfe24SRichard Henderson float32 uint64_to_float32_scalbn(uint64_t, int, float_status *status);
2142abdfe24SRichard Henderson 
215c02e1fb8SAlex Bennée float32 int16_to_float32(int16_t, float_status *status);
216e5a41ffaSPeter Maydell float32 int32_to_float32(int32_t, float_status *status);
2172abdfe24SRichard Henderson float32 int64_to_float32(int64_t, float_status *status);
218c02e1fb8SAlex Bennée float32 uint16_to_float32(uint16_t, float_status *status);
219e5a41ffaSPeter Maydell float32 uint32_to_float32(uint32_t, float_status *status);
2202abdfe24SRichard Henderson float32 uint64_to_float32(uint64_t, float_status *status);
2212abdfe24SRichard Henderson 
2222abdfe24SRichard Henderson float64 int16_to_float64_scalbn(int16_t, int, float_status *status);
2232abdfe24SRichard Henderson float64 int32_to_float64_scalbn(int32_t, int, float_status *status);
2242abdfe24SRichard Henderson float64 int64_to_float64_scalbn(int64_t, int, float_status *status);
2252abdfe24SRichard Henderson float64 uint16_to_float64_scalbn(uint16_t, int, float_status *status);
2262abdfe24SRichard Henderson float64 uint32_to_float64_scalbn(uint32_t, int, float_status *status);
2272abdfe24SRichard Henderson float64 uint64_to_float64_scalbn(uint64_t, int, float_status *status);
2282abdfe24SRichard Henderson 
2292abdfe24SRichard Henderson float64 int16_to_float64(int16_t, float_status *status);
2302abdfe24SRichard Henderson float64 int32_to_float64(int32_t, float_status *status);
2312abdfe24SRichard Henderson float64 int64_to_float64(int64_t, float_status *status);
232c02e1fb8SAlex Bennée float64 uint16_to_float64(uint16_t, float_status *status);
233e5a41ffaSPeter Maydell float64 uint32_to_float64(uint32_t, float_status *status);
234e5a41ffaSPeter Maydell float64 uint64_to_float64(uint64_t, float_status *status);
2352abdfe24SRichard Henderson 
2362abdfe24SRichard Henderson floatx80 int32_to_floatx80(int32_t, float_status *status);
2372abdfe24SRichard Henderson floatx80 int64_to_floatx80(int64_t, float_status *status);
2382abdfe24SRichard Henderson 
2392abdfe24SRichard Henderson float128 int32_to_float128(int32_t, float_status *status);
2402abdfe24SRichard Henderson float128 int64_to_float128(int64_t, float_status *status);
241e5a41ffaSPeter Maydell float128 uint64_to_float128(uint64_t, float_status *status);
2426b4c305cSPaolo Bonzini 
2436b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
2446b4c305cSPaolo Bonzini | Software half-precision conversion routines.
2456b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
2462f6c74beSRichard Henderson 
2476fed16b2SAlex Bennée float16 float32_to_float16(float32, bool ieee, float_status *status);
2486fed16b2SAlex Bennée float32 float16_to_float32(float16, bool ieee, float_status *status);
2496fed16b2SAlex Bennée float16 float64_to_float16(float64 a, bool ieee, float_status *status);
2506fed16b2SAlex Bennée float64 float16_to_float64(float16 a, bool ieee, float_status *status);
2512f6c74beSRichard Henderson 
2522f6c74beSRichard Henderson int16_t float16_to_int16_scalbn(float16, int, int, float_status *status);
2532f6c74beSRichard Henderson int32_t float16_to_int32_scalbn(float16, int, int, float_status *status);
2542f6c74beSRichard Henderson int64_t float16_to_int64_scalbn(float16, int, int, float_status *status);
2552f6c74beSRichard Henderson 
256ab52f973SAlex Bennée int16_t float16_to_int16(float16, float_status *status);
257ab52f973SAlex Bennée int32_t float16_to_int32(float16, float_status *status);
258ab52f973SAlex Bennée int64_t float16_to_int64(float16, float_status *status);
2592f6c74beSRichard Henderson 
2602f6c74beSRichard Henderson int16_t float16_to_int16_round_to_zero(float16, float_status *status);
2612f6c74beSRichard Henderson int32_t float16_to_int32_round_to_zero(float16, float_status *status);
262ab52f973SAlex Bennée int64_t float16_to_int64_round_to_zero(float16, float_status *status);
2632f6c74beSRichard Henderson 
2642f6c74beSRichard Henderson uint16_t float16_to_uint16_scalbn(float16 a, int, int, float_status *status);
2652f6c74beSRichard Henderson uint32_t float16_to_uint32_scalbn(float16 a, int, int, float_status *status);
2662f6c74beSRichard Henderson uint64_t float16_to_uint64_scalbn(float16 a, int, int, float_status *status);
2672f6c74beSRichard Henderson 
2682f6c74beSRichard Henderson uint16_t float16_to_uint16(float16 a, float_status *status);
2692f6c74beSRichard Henderson uint32_t float16_to_uint32(float16 a, float_status *status);
2702f6c74beSRichard Henderson uint64_t float16_to_uint64(float16 a, float_status *status);
2712f6c74beSRichard Henderson 
2722f6c74beSRichard Henderson uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status);
2732f6c74beSRichard Henderson uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status);
274ab52f973SAlex Bennée uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status);
2756b4c305cSPaolo Bonzini 
2766b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
2776b4c305cSPaolo Bonzini | Software half-precision operations.
2786b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
2796fff2167SAlex Bennée 
280dbe4d53aSAlex Bennée float16 float16_round_to_int(float16, float_status *status);
2816fff2167SAlex Bennée float16 float16_add(float16, float16, float_status *status);
2826fff2167SAlex Bennée float16 float16_sub(float16, float16, float_status *status);
28374d707e2SAlex Bennée float16 float16_mul(float16, float16, float_status *status);
284d446830aSAlex Bennée float16 float16_muladd(float16, float16, float16, int, float_status *status);
285cf07323dSAlex Bennée float16 float16_div(float16, float16, float_status *status);
2860bfc9f19SAlex Bennée float16 float16_scalbn(float16, int, float_status *status);
28789360067SAlex Bennée float16 float16_min(float16, float16, float_status *status);
28889360067SAlex Bennée float16 float16_max(float16, float16, float_status *status);
28989360067SAlex Bennée float16 float16_minnum(float16, float16, float_status *status);
29089360067SAlex Bennée float16 float16_maxnum(float16, float16, float_status *status);
29189360067SAlex Bennée float16 float16_minnummag(float16, float16, float_status *status);
29289360067SAlex Bennée float16 float16_maxnummag(float16, float16, float_status *status);
293c13bb2daSAlex Bennée float16 float16_sqrt(float16, float_status *status);
2940c4c9092SAlex Bennée int float16_compare(float16, float16, float_status *status);
2950c4c9092SAlex Bennée int float16_compare_quiet(float16, float16, float_status *status);
2966fff2167SAlex Bennée 
297af39bc8cSAleksandar Markovic int float16_is_quiet_nan(float16, float_status *status);
298af39bc8cSAleksandar Markovic int float16_is_signaling_nan(float16, float_status *status);
299d619bb98SRichard Henderson float16 float16_silence_nan(float16, float_status *status);
3006b4c305cSPaolo Bonzini 
301a49db98dSLuiz Capitulino static inline int float16_is_any_nan(float16 a)
3026b4c305cSPaolo Bonzini {
3036b4c305cSPaolo Bonzini     return ((float16_val(a) & ~0x8000) > 0x7c00);
3046b4c305cSPaolo Bonzini }
3056b4c305cSPaolo Bonzini 
306f566c047SBharata B Rao static inline int float16_is_neg(float16 a)
307f566c047SBharata B Rao {
308f566c047SBharata B Rao     return float16_val(a) >> 15;
309f566c047SBharata B Rao }
310f566c047SBharata B Rao 
311f566c047SBharata B Rao static inline int float16_is_infinity(float16 a)
312f566c047SBharata B Rao {
313f566c047SBharata B Rao     return (float16_val(a) & 0x7fff) == 0x7c00;
314f566c047SBharata B Rao }
315f566c047SBharata B Rao 
316f566c047SBharata B Rao static inline int float16_is_zero(float16 a)
317f566c047SBharata B Rao {
318f566c047SBharata B Rao     return (float16_val(a) & 0x7fff) == 0;
319f566c047SBharata B Rao }
320f566c047SBharata B Rao 
321f566c047SBharata B Rao static inline int float16_is_zero_or_denormal(float16 a)
322f566c047SBharata B Rao {
323f566c047SBharata B Rao     return (float16_val(a) & 0x7c00) == 0;
324f566c047SBharata B Rao }
325f566c047SBharata B Rao 
32628136775SAlex Bennée static inline float16 float16_abs(float16 a)
32728136775SAlex Bennée {
32828136775SAlex Bennée     /* Note that abs does *not* handle NaN specially, nor does
32928136775SAlex Bennée      * it flush denormal inputs to zero.
33028136775SAlex Bennée      */
33128136775SAlex Bennée     return make_float16(float16_val(a) & 0x7fff);
33228136775SAlex Bennée }
3335f10aef5SAlex Bennée 
3345f10aef5SAlex Bennée static inline float16 float16_chs(float16 a)
3355f10aef5SAlex Bennée {
3365f10aef5SAlex Bennée     /* Note that chs does *not* handle NaN specially, nor does
3375f10aef5SAlex Bennée      * it flush denormal inputs to zero.
3385f10aef5SAlex Bennée      */
3395f10aef5SAlex Bennée     return make_float16(float16_val(a) ^ 0x8000);
3405f10aef5SAlex Bennée }
3415f10aef5SAlex Bennée 
34278b5a3e6SAlex Bennée static inline float16 float16_set_sign(float16 a, int sign)
34378b5a3e6SAlex Bennée {
34478b5a3e6SAlex Bennée     return make_float16((float16_val(a) & 0x7fff) | (sign << 15));
34578b5a3e6SAlex Bennée }
34678b5a3e6SAlex Bennée 
347efd4829eSAlex Bennée #define float16_zero make_float16(0)
348efd4829eSAlex Bennée #define float16_half make_float16(0x3800)
349026e2d6eSAlex Bennée #define float16_one make_float16(0x3c00)
350026e2d6eSAlex Bennée #define float16_one_point_five make_float16(0x3e00)
351026e2d6eSAlex Bennée #define float16_two make_float16(0x4000)
352026e2d6eSAlex Bennée #define float16_three make_float16(0x4200)
353efd4829eSAlex Bennée #define float16_infinity make_float16(0x7c00)
354efd4829eSAlex Bennée 
3556b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3566b4c305cSPaolo Bonzini | The pattern for a default generated half-precision NaN.
3576b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
358af39bc8cSAleksandar Markovic float16 float16_default_nan(float_status *status);
3596b4c305cSPaolo Bonzini 
3606b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3616b4c305cSPaolo Bonzini | Software IEC/IEEE single-precision conversion routines.
3626b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
3632f6c74beSRichard Henderson 
3642f6c74beSRichard Henderson int16_t float32_to_int16_scalbn(float32, int, int, float_status *status);
3652f6c74beSRichard Henderson int32_t float32_to_int32_scalbn(float32, int, int, float_status *status);
3662f6c74beSRichard Henderson int64_t float32_to_int64_scalbn(float32, int, int, float_status *status);
3672f6c74beSRichard Henderson 
3680bb721d7SPeter Maydell int16_t float32_to_int16(float32, float_status *status);
369f4014512SPeter Maydell int32_t float32_to_int32(float32, float_status *status);
370f42c2224SPeter Maydell int64_t float32_to_int64(float32, float_status *status);
3712f6c74beSRichard Henderson 
3722f6c74beSRichard Henderson int16_t float32_to_int16_round_to_zero(float32, float_status *status);
3732f6c74beSRichard Henderson int32_t float32_to_int32_round_to_zero(float32, float_status *status);
374f42c2224SPeter Maydell int64_t float32_to_int64_round_to_zero(float32, float_status *status);
3752f6c74beSRichard Henderson 
3762f6c74beSRichard Henderson uint16_t float32_to_uint16_scalbn(float32, int, int, float_status *status);
3772f6c74beSRichard Henderson uint32_t float32_to_uint32_scalbn(float32, int, int, float_status *status);
3782f6c74beSRichard Henderson uint64_t float32_to_uint64_scalbn(float32, int, int, float_status *status);
3792f6c74beSRichard Henderson 
3802f6c74beSRichard Henderson uint16_t float32_to_uint16(float32, float_status *status);
3812f6c74beSRichard Henderson uint32_t float32_to_uint32(float32, float_status *status);
3822f6c74beSRichard Henderson uint64_t float32_to_uint64(float32, float_status *status);
3832f6c74beSRichard Henderson 
3842f6c74beSRichard Henderson uint16_t float32_to_uint16_round_to_zero(float32, float_status *status);
3852f6c74beSRichard Henderson uint32_t float32_to_uint32_round_to_zero(float32, float_status *status);
3862f6c74beSRichard Henderson uint64_t float32_to_uint64_round_to_zero(float32, float_status *status);
3872f6c74beSRichard Henderson 
388e5a41ffaSPeter Maydell float64 float32_to_float64(float32, float_status *status);
389e5a41ffaSPeter Maydell floatx80 float32_to_floatx80(float32, float_status *status);
390e5a41ffaSPeter Maydell float128 float32_to_float128(float32, float_status *status);
3916b4c305cSPaolo Bonzini 
3926b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
3936b4c305cSPaolo Bonzini | Software IEC/IEEE single-precision operations.
3946b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
395e5a41ffaSPeter Maydell float32 float32_round_to_int(float32, float_status *status);
396e5a41ffaSPeter Maydell float32 float32_add(float32, float32, float_status *status);
397e5a41ffaSPeter Maydell float32 float32_sub(float32, float32, float_status *status);
398e5a41ffaSPeter Maydell float32 float32_mul(float32, float32, float_status *status);
399e5a41ffaSPeter Maydell float32 float32_div(float32, float32, float_status *status);
400e5a41ffaSPeter Maydell float32 float32_rem(float32, float32, float_status *status);
401e5a41ffaSPeter Maydell float32 float32_muladd(float32, float32, float32, int, float_status *status);
402e5a41ffaSPeter Maydell float32 float32_sqrt(float32, float_status *status);
403e5a41ffaSPeter Maydell float32 float32_exp2(float32, float_status *status);
404e5a41ffaSPeter Maydell float32 float32_log2(float32, float_status *status);
405e5a41ffaSPeter Maydell int float32_eq(float32, float32, float_status *status);
406e5a41ffaSPeter Maydell int float32_le(float32, float32, float_status *status);
407e5a41ffaSPeter Maydell int float32_lt(float32, float32, float_status *status);
408e5a41ffaSPeter Maydell int float32_unordered(float32, float32, float_status *status);
409e5a41ffaSPeter Maydell int float32_eq_quiet(float32, float32, float_status *status);
410e5a41ffaSPeter Maydell int float32_le_quiet(float32, float32, float_status *status);
411e5a41ffaSPeter Maydell int float32_lt_quiet(float32, float32, float_status *status);
412e5a41ffaSPeter Maydell int float32_unordered_quiet(float32, float32, float_status *status);
413e5a41ffaSPeter Maydell int float32_compare(float32, float32, float_status *status);
414e5a41ffaSPeter Maydell int float32_compare_quiet(float32, float32, float_status *status);
415e5a41ffaSPeter Maydell float32 float32_min(float32, float32, float_status *status);
416e5a41ffaSPeter Maydell float32 float32_max(float32, float32, float_status *status);
417e5a41ffaSPeter Maydell float32 float32_minnum(float32, float32, float_status *status);
418e5a41ffaSPeter Maydell float32 float32_maxnum(float32, float32, float_status *status);
419e5a41ffaSPeter Maydell float32 float32_minnummag(float32, float32, float_status *status);
420e5a41ffaSPeter Maydell float32 float32_maxnummag(float32, float32, float_status *status);
421af39bc8cSAleksandar Markovic int float32_is_quiet_nan(float32, float_status *status);
422af39bc8cSAleksandar Markovic int float32_is_signaling_nan(float32, float_status *status);
423d619bb98SRichard Henderson float32 float32_silence_nan(float32, float_status *status);
424e5a41ffaSPeter Maydell float32 float32_scalbn(float32, int, float_status *status);
4256b4c305cSPaolo Bonzini 
426a49db98dSLuiz Capitulino static inline float32 float32_abs(float32 a)
4276b4c305cSPaolo Bonzini {
4286b4c305cSPaolo Bonzini     /* Note that abs does *not* handle NaN specially, nor does
4296b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
4306b4c305cSPaolo Bonzini      */
4316b4c305cSPaolo Bonzini     return make_float32(float32_val(a) & 0x7fffffff);
4326b4c305cSPaolo Bonzini }
4336b4c305cSPaolo Bonzini 
434a49db98dSLuiz Capitulino static inline float32 float32_chs(float32 a)
4356b4c305cSPaolo Bonzini {
4366b4c305cSPaolo Bonzini     /* Note that chs does *not* handle NaN specially, nor does
4376b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
4386b4c305cSPaolo Bonzini      */
4396b4c305cSPaolo Bonzini     return make_float32(float32_val(a) ^ 0x80000000);
4406b4c305cSPaolo Bonzini }
4416b4c305cSPaolo Bonzini 
442a49db98dSLuiz Capitulino static inline int float32_is_infinity(float32 a)
4436b4c305cSPaolo Bonzini {
4446b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7fffffff) == 0x7f800000;
4456b4c305cSPaolo Bonzini }
4466b4c305cSPaolo Bonzini 
447a49db98dSLuiz Capitulino static inline int float32_is_neg(float32 a)
4486b4c305cSPaolo Bonzini {
4496b4c305cSPaolo Bonzini     return float32_val(a) >> 31;
4506b4c305cSPaolo Bonzini }
4516b4c305cSPaolo Bonzini 
452a49db98dSLuiz Capitulino static inline int float32_is_zero(float32 a)
4536b4c305cSPaolo Bonzini {
4546b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7fffffff) == 0;
4556b4c305cSPaolo Bonzini }
4566b4c305cSPaolo Bonzini 
457a49db98dSLuiz Capitulino static inline int float32_is_any_nan(float32 a)
4586b4c305cSPaolo Bonzini {
4596b4c305cSPaolo Bonzini     return ((float32_val(a) & ~(1 << 31)) > 0x7f800000UL);
4606b4c305cSPaolo Bonzini }
4616b4c305cSPaolo Bonzini 
462a49db98dSLuiz Capitulino static inline int float32_is_zero_or_denormal(float32 a)
4636b4c305cSPaolo Bonzini {
4646b4c305cSPaolo Bonzini     return (float32_val(a) & 0x7f800000) == 0;
4656b4c305cSPaolo Bonzini }
4666b4c305cSPaolo Bonzini 
467*588e6dfdSEmilio G. Cota static inline bool float32_is_normal(float32 a)
468*588e6dfdSEmilio G. Cota {
469*588e6dfdSEmilio G. Cota     return ((float32_val(a) + 0x00800000) & 0x7fffffff) >= 0x01000000;
470*588e6dfdSEmilio G. Cota }
471*588e6dfdSEmilio G. Cota 
472*588e6dfdSEmilio G. Cota static inline bool float32_is_denormal(float32 a)
473*588e6dfdSEmilio G. Cota {
474*588e6dfdSEmilio G. Cota     return float32_is_zero_or_denormal(a) && !float32_is_zero(a);
475*588e6dfdSEmilio G. Cota }
476*588e6dfdSEmilio G. Cota 
477a49db98dSLuiz Capitulino static inline float32 float32_set_sign(float32 a, int sign)
4786b4c305cSPaolo Bonzini {
4796b4c305cSPaolo Bonzini     return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31));
4806b4c305cSPaolo Bonzini }
4816b4c305cSPaolo Bonzini 
4826b4c305cSPaolo Bonzini #define float32_zero make_float32(0)
4836b4c305cSPaolo Bonzini #define float32_half make_float32(0x3f000000)
484026e2d6eSAlex Bennée #define float32_one make_float32(0x3f800000)
485026e2d6eSAlex Bennée #define float32_one_point_five make_float32(0x3fc00000)
486026e2d6eSAlex Bennée #define float32_two make_float32(0x40000000)
487026e2d6eSAlex Bennée #define float32_three make_float32(0x40400000)
4886b4c305cSPaolo Bonzini #define float32_infinity make_float32(0x7f800000)
4896b4c305cSPaolo Bonzini 
4906b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
49188857acaSLaurent Vivier | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
49288857acaSLaurent Vivier | single-precision floating-point value, returning the result.  After being
49388857acaSLaurent Vivier | shifted into the proper positions, the three fields are simply added
49488857acaSLaurent Vivier | together to form the result.  This means that any integer portion of `zSig'
49588857acaSLaurent Vivier | will be added into the exponent.  Since a properly normalized significand
49688857acaSLaurent Vivier | will have an integer portion equal to 1, the `zExp' input should be 1 less
49788857acaSLaurent Vivier | than the desired result exponent whenever `zSig' is a complete, normalized
49888857acaSLaurent Vivier | significand.
49988857acaSLaurent Vivier *----------------------------------------------------------------------------*/
50088857acaSLaurent Vivier 
50188857acaSLaurent Vivier static inline float32 packFloat32(flag zSign, int zExp, uint32_t zSig)
50288857acaSLaurent Vivier {
50388857acaSLaurent Vivier     return make_float32(
50488857acaSLaurent Vivier           (((uint32_t)zSign) << 31) + (((uint32_t)zExp) << 23) + zSig);
50588857acaSLaurent Vivier }
50688857acaSLaurent Vivier 
50788857acaSLaurent Vivier /*----------------------------------------------------------------------------
5086b4c305cSPaolo Bonzini | The pattern for a default generated single-precision NaN.
5096b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
510af39bc8cSAleksandar Markovic float32 float32_default_nan(float_status *status);
5116b4c305cSPaolo Bonzini 
5126b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
5136b4c305cSPaolo Bonzini | Software IEC/IEEE double-precision conversion routines.
5146b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
5152f6c74beSRichard Henderson 
5162f6c74beSRichard Henderson int16_t float64_to_int16_scalbn(float64, int, int, float_status *status);
5172f6c74beSRichard Henderson int32_t float64_to_int32_scalbn(float64, int, int, float_status *status);
5182f6c74beSRichard Henderson int64_t float64_to_int64_scalbn(float64, int, int, float_status *status);
5192f6c74beSRichard Henderson 
5200bb721d7SPeter Maydell int16_t float64_to_int16(float64, float_status *status);
521f4014512SPeter Maydell int32_t float64_to_int32(float64, float_status *status);
522f42c2224SPeter Maydell int64_t float64_to_int64(float64, float_status *status);
5232f6c74beSRichard Henderson 
5242f6c74beSRichard Henderson int16_t float64_to_int16_round_to_zero(float64, float_status *status);
5252f6c74beSRichard Henderson int32_t float64_to_int32_round_to_zero(float64, float_status *status);
526f42c2224SPeter Maydell int64_t float64_to_int64_round_to_zero(float64, float_status *status);
5272f6c74beSRichard Henderson 
5282f6c74beSRichard Henderson uint16_t float64_to_uint16_scalbn(float64, int, int, float_status *status);
5292f6c74beSRichard Henderson uint32_t float64_to_uint32_scalbn(float64, int, int, float_status *status);
5302f6c74beSRichard Henderson uint64_t float64_to_uint64_scalbn(float64, int, int, float_status *status);
5312f6c74beSRichard Henderson 
5322f6c74beSRichard Henderson uint16_t float64_to_uint16(float64, float_status *status);
5332f6c74beSRichard Henderson uint32_t float64_to_uint32(float64, float_status *status);
5342f6c74beSRichard Henderson uint64_t float64_to_uint64(float64, float_status *status);
5352f6c74beSRichard Henderson 
5362f6c74beSRichard Henderson uint16_t float64_to_uint16_round_to_zero(float64, float_status *status);
5372f6c74beSRichard Henderson uint32_t float64_to_uint32_round_to_zero(float64, float_status *status);
5382f6c74beSRichard Henderson uint64_t float64_to_uint64_round_to_zero(float64, float_status *status);
5392f6c74beSRichard Henderson 
540e5a41ffaSPeter Maydell float32 float64_to_float32(float64, float_status *status);
541e5a41ffaSPeter Maydell floatx80 float64_to_floatx80(float64, float_status *status);
542e5a41ffaSPeter Maydell float128 float64_to_float128(float64, float_status *status);
5436b4c305cSPaolo Bonzini 
5446b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
5456b4c305cSPaolo Bonzini | Software IEC/IEEE double-precision operations.
5466b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
547e5a41ffaSPeter Maydell float64 float64_round_to_int(float64, float_status *status);
548e5a41ffaSPeter Maydell float64 float64_add(float64, float64, float_status *status);
549e5a41ffaSPeter Maydell float64 float64_sub(float64, float64, float_status *status);
550e5a41ffaSPeter Maydell float64 float64_mul(float64, float64, float_status *status);
551e5a41ffaSPeter Maydell float64 float64_div(float64, float64, float_status *status);
552e5a41ffaSPeter Maydell float64 float64_rem(float64, float64, float_status *status);
553e5a41ffaSPeter Maydell float64 float64_muladd(float64, float64, float64, int, float_status *status);
554e5a41ffaSPeter Maydell float64 float64_sqrt(float64, float_status *status);
555e5a41ffaSPeter Maydell float64 float64_log2(float64, float_status *status);
556e5a41ffaSPeter Maydell int float64_eq(float64, float64, float_status *status);
557e5a41ffaSPeter Maydell int float64_le(float64, float64, float_status *status);
558e5a41ffaSPeter Maydell int float64_lt(float64, float64, float_status *status);
559e5a41ffaSPeter Maydell int float64_unordered(float64, float64, float_status *status);
560e5a41ffaSPeter Maydell int float64_eq_quiet(float64, float64, float_status *status);
561e5a41ffaSPeter Maydell int float64_le_quiet(float64, float64, float_status *status);
562e5a41ffaSPeter Maydell int float64_lt_quiet(float64, float64, float_status *status);
563e5a41ffaSPeter Maydell int float64_unordered_quiet(float64, float64, float_status *status);
564e5a41ffaSPeter Maydell int float64_compare(float64, float64, float_status *status);
565e5a41ffaSPeter Maydell int float64_compare_quiet(float64, float64, float_status *status);
566e5a41ffaSPeter Maydell float64 float64_min(float64, float64, float_status *status);
567e5a41ffaSPeter Maydell float64 float64_max(float64, float64, float_status *status);
568e5a41ffaSPeter Maydell float64 float64_minnum(float64, float64, float_status *status);
569e5a41ffaSPeter Maydell float64 float64_maxnum(float64, float64, float_status *status);
570e5a41ffaSPeter Maydell float64 float64_minnummag(float64, float64, float_status *status);
571e5a41ffaSPeter Maydell float64 float64_maxnummag(float64, float64, float_status *status);
572af39bc8cSAleksandar Markovic int float64_is_quiet_nan(float64 a, float_status *status);
573af39bc8cSAleksandar Markovic int float64_is_signaling_nan(float64, float_status *status);
574d619bb98SRichard Henderson float64 float64_silence_nan(float64, float_status *status);
575e5a41ffaSPeter Maydell float64 float64_scalbn(float64, int, float_status *status);
5766b4c305cSPaolo Bonzini 
577a49db98dSLuiz Capitulino static inline float64 float64_abs(float64 a)
5786b4c305cSPaolo Bonzini {
5796b4c305cSPaolo Bonzini     /* Note that abs does *not* handle NaN specially, nor does
5806b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
5816b4c305cSPaolo Bonzini      */
5826b4c305cSPaolo Bonzini     return make_float64(float64_val(a) & 0x7fffffffffffffffLL);
5836b4c305cSPaolo Bonzini }
5846b4c305cSPaolo Bonzini 
585a49db98dSLuiz Capitulino static inline float64 float64_chs(float64 a)
5866b4c305cSPaolo Bonzini {
5876b4c305cSPaolo Bonzini     /* Note that chs does *not* handle NaN specially, nor does
5886b4c305cSPaolo Bonzini      * it flush denormal inputs to zero.
5896b4c305cSPaolo Bonzini      */
5906b4c305cSPaolo Bonzini     return make_float64(float64_val(a) ^ 0x8000000000000000LL);
5916b4c305cSPaolo Bonzini }
5926b4c305cSPaolo Bonzini 
593a49db98dSLuiz Capitulino static inline int float64_is_infinity(float64 a)
5946b4c305cSPaolo Bonzini {
5956b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL;
5966b4c305cSPaolo Bonzini }
5976b4c305cSPaolo Bonzini 
598a49db98dSLuiz Capitulino static inline int float64_is_neg(float64 a)
5996b4c305cSPaolo Bonzini {
6006b4c305cSPaolo Bonzini     return float64_val(a) >> 63;
6016b4c305cSPaolo Bonzini }
6026b4c305cSPaolo Bonzini 
603a49db98dSLuiz Capitulino static inline int float64_is_zero(float64 a)
6046b4c305cSPaolo Bonzini {
6056b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7fffffffffffffffLL) == 0;
6066b4c305cSPaolo Bonzini }
6076b4c305cSPaolo Bonzini 
608a49db98dSLuiz Capitulino static inline int float64_is_any_nan(float64 a)
6096b4c305cSPaolo Bonzini {
6106b4c305cSPaolo Bonzini     return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL);
6116b4c305cSPaolo Bonzini }
6126b4c305cSPaolo Bonzini 
613a49db98dSLuiz Capitulino static inline int float64_is_zero_or_denormal(float64 a)
6146b4c305cSPaolo Bonzini {
6156b4c305cSPaolo Bonzini     return (float64_val(a) & 0x7ff0000000000000LL) == 0;
6166b4c305cSPaolo Bonzini }
6176b4c305cSPaolo Bonzini 
618*588e6dfdSEmilio G. Cota static inline bool float64_is_normal(float64 a)
619*588e6dfdSEmilio G. Cota {
620*588e6dfdSEmilio G. Cota     return ((float64_val(a) + (1ULL << 52)) & -1ULL >> 1) >= 1ULL << 53;
621*588e6dfdSEmilio G. Cota }
622*588e6dfdSEmilio G. Cota 
623*588e6dfdSEmilio G. Cota static inline bool float64_is_denormal(float64 a)
624*588e6dfdSEmilio G. Cota {
625*588e6dfdSEmilio G. Cota     return float64_is_zero_or_denormal(a) && !float64_is_zero(a);
626*588e6dfdSEmilio G. Cota }
627*588e6dfdSEmilio G. Cota 
628a49db98dSLuiz Capitulino static inline float64 float64_set_sign(float64 a, int sign)
6296b4c305cSPaolo Bonzini {
6306b4c305cSPaolo Bonzini     return make_float64((float64_val(a) & 0x7fffffffffffffffULL)
6316b4c305cSPaolo Bonzini                         | ((int64_t)sign << 63));
6326b4c305cSPaolo Bonzini }
6336b4c305cSPaolo Bonzini 
6346b4c305cSPaolo Bonzini #define float64_zero make_float64(0)
6356b4c305cSPaolo Bonzini #define float64_half make_float64(0x3fe0000000000000LL)
636026e2d6eSAlex Bennée #define float64_one make_float64(0x3ff0000000000000LL)
637026e2d6eSAlex Bennée #define float64_one_point_five make_float64(0x3FF8000000000000ULL)
638026e2d6eSAlex Bennée #define float64_two make_float64(0x4000000000000000ULL)
639026e2d6eSAlex Bennée #define float64_three make_float64(0x4008000000000000ULL)
640026e2d6eSAlex Bennée #define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
6416b4c305cSPaolo Bonzini #define float64_infinity make_float64(0x7ff0000000000000LL)
6426b4c305cSPaolo Bonzini 
6436b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
6446b4c305cSPaolo Bonzini | The pattern for a default generated double-precision NaN.
6456b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
646af39bc8cSAleksandar Markovic float64 float64_default_nan(float_status *status);
6476b4c305cSPaolo Bonzini 
6486b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
6496b4c305cSPaolo Bonzini | Software IEC/IEEE extended double-precision conversion routines.
6506b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
651f4014512SPeter Maydell int32_t floatx80_to_int32(floatx80, float_status *status);
652f4014512SPeter Maydell int32_t floatx80_to_int32_round_to_zero(floatx80, float_status *status);
653f42c2224SPeter Maydell int64_t floatx80_to_int64(floatx80, float_status *status);
654f42c2224SPeter Maydell int64_t floatx80_to_int64_round_to_zero(floatx80, float_status *status);
655e5a41ffaSPeter Maydell float32 floatx80_to_float32(floatx80, float_status *status);
656e5a41ffaSPeter Maydell float64 floatx80_to_float64(floatx80, float_status *status);
657e5a41ffaSPeter Maydell float128 floatx80_to_float128(floatx80, float_status *status);
6586b4c305cSPaolo Bonzini 
6596b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
6600f605c88SLaurent Vivier | The pattern for an extended double-precision inf.
6610f605c88SLaurent Vivier *----------------------------------------------------------------------------*/
6620f605c88SLaurent Vivier extern const floatx80 floatx80_infinity;
6630f605c88SLaurent Vivier 
6640f605c88SLaurent Vivier /*----------------------------------------------------------------------------
6656b4c305cSPaolo Bonzini | Software IEC/IEEE extended double-precision operations.
6666b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
6670f721292SLaurent Vivier floatx80 floatx80_round(floatx80 a, float_status *status);
668e5a41ffaSPeter Maydell floatx80 floatx80_round_to_int(floatx80, float_status *status);
669e5a41ffaSPeter Maydell floatx80 floatx80_add(floatx80, floatx80, float_status *status);
670e5a41ffaSPeter Maydell floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
671e5a41ffaSPeter Maydell floatx80 floatx80_mul(floatx80, floatx80, float_status *status);
672e5a41ffaSPeter Maydell floatx80 floatx80_div(floatx80, floatx80, float_status *status);
673e5a41ffaSPeter Maydell floatx80 floatx80_rem(floatx80, floatx80, float_status *status);
674e5a41ffaSPeter Maydell floatx80 floatx80_sqrt(floatx80, float_status *status);
675e5a41ffaSPeter Maydell int floatx80_eq(floatx80, floatx80, float_status *status);
676e5a41ffaSPeter Maydell int floatx80_le(floatx80, floatx80, float_status *status);
677e5a41ffaSPeter Maydell int floatx80_lt(floatx80, floatx80, float_status *status);
678e5a41ffaSPeter Maydell int floatx80_unordered(floatx80, floatx80, float_status *status);
679e5a41ffaSPeter Maydell int floatx80_eq_quiet(floatx80, floatx80, float_status *status);
680e5a41ffaSPeter Maydell int floatx80_le_quiet(floatx80, floatx80, float_status *status);
681e5a41ffaSPeter Maydell int floatx80_lt_quiet(floatx80, floatx80, float_status *status);
682e5a41ffaSPeter Maydell int floatx80_unordered_quiet(floatx80, floatx80, float_status *status);
683e5a41ffaSPeter Maydell int floatx80_compare(floatx80, floatx80, float_status *status);
684e5a41ffaSPeter Maydell int floatx80_compare_quiet(floatx80, floatx80, float_status *status);
685af39bc8cSAleksandar Markovic int floatx80_is_quiet_nan(floatx80, float_status *status);
686af39bc8cSAleksandar Markovic int floatx80_is_signaling_nan(floatx80, float_status *status);
687d619bb98SRichard Henderson floatx80 floatx80_silence_nan(floatx80, float_status *status);
688e5a41ffaSPeter Maydell floatx80 floatx80_scalbn(floatx80, int, float_status *status);
6896b4c305cSPaolo Bonzini 
690a49db98dSLuiz Capitulino static inline floatx80 floatx80_abs(floatx80 a)
6916b4c305cSPaolo Bonzini {
6926b4c305cSPaolo Bonzini     a.high &= 0x7fff;
6936b4c305cSPaolo Bonzini     return a;
6946b4c305cSPaolo Bonzini }
6956b4c305cSPaolo Bonzini 
696a49db98dSLuiz Capitulino static inline floatx80 floatx80_chs(floatx80 a)
6976b4c305cSPaolo Bonzini {
6986b4c305cSPaolo Bonzini     a.high ^= 0x8000;
6996b4c305cSPaolo Bonzini     return a;
7006b4c305cSPaolo Bonzini }
7016b4c305cSPaolo Bonzini 
702a49db98dSLuiz Capitulino static inline int floatx80_is_infinity(floatx80 a)
7036b4c305cSPaolo Bonzini {
7040f605c88SLaurent Vivier #if defined(TARGET_M68K)
7050f605c88SLaurent Vivier     return (a.high & 0x7fff) == floatx80_infinity.high && !(a.low << 1);
7060f605c88SLaurent Vivier #else
7070f605c88SLaurent Vivier     return (a.high & 0x7fff) == floatx80_infinity.high &&
7080f605c88SLaurent Vivier                        a.low == floatx80_infinity.low;
7090f605c88SLaurent Vivier #endif
7106b4c305cSPaolo Bonzini }
7116b4c305cSPaolo Bonzini 
712a49db98dSLuiz Capitulino static inline int floatx80_is_neg(floatx80 a)
7136b4c305cSPaolo Bonzini {
7146b4c305cSPaolo Bonzini     return a.high >> 15;
7156b4c305cSPaolo Bonzini }
7166b4c305cSPaolo Bonzini 
717a49db98dSLuiz Capitulino static inline int floatx80_is_zero(floatx80 a)
7186b4c305cSPaolo Bonzini {
7196b4c305cSPaolo Bonzini     return (a.high & 0x7fff) == 0 && a.low == 0;
7206b4c305cSPaolo Bonzini }
7216b4c305cSPaolo Bonzini 
722a49db98dSLuiz Capitulino static inline int floatx80_is_zero_or_denormal(floatx80 a)
7236b4c305cSPaolo Bonzini {
7246b4c305cSPaolo Bonzini     return (a.high & 0x7fff) == 0;
7256b4c305cSPaolo Bonzini }
7266b4c305cSPaolo Bonzini 
727a49db98dSLuiz Capitulino static inline int floatx80_is_any_nan(floatx80 a)
7286b4c305cSPaolo Bonzini {
7296b4c305cSPaolo Bonzini     return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
7306b4c305cSPaolo Bonzini }
7316b4c305cSPaolo Bonzini 
732d1eb8f2aSAndrew Dutcher /*----------------------------------------------------------------------------
733d1eb8f2aSAndrew Dutcher | Return whether the given value is an invalid floatx80 encoding.
734d1eb8f2aSAndrew Dutcher | Invalid floatx80 encodings arise when the integer bit is not set, but
735d1eb8f2aSAndrew Dutcher | the exponent is not zero. The only times the integer bit is permitted to
736d1eb8f2aSAndrew Dutcher | be zero is in subnormal numbers and the value zero.
737d1eb8f2aSAndrew Dutcher | This includes what the Intel software developer's manual calls pseudo-NaNs,
738d1eb8f2aSAndrew Dutcher | pseudo-infinities and un-normal numbers. It does not include
739d1eb8f2aSAndrew Dutcher | pseudo-denormals, which must still be correctly handled as inputs even
740d1eb8f2aSAndrew Dutcher | if they are never generated as outputs.
741d1eb8f2aSAndrew Dutcher *----------------------------------------------------------------------------*/
742d1eb8f2aSAndrew Dutcher static inline bool floatx80_invalid_encoding(floatx80 a)
743d1eb8f2aSAndrew Dutcher {
744d1eb8f2aSAndrew Dutcher     return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0;
745d1eb8f2aSAndrew Dutcher }
746d1eb8f2aSAndrew Dutcher 
7476b4c305cSPaolo Bonzini #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
7486b4c305cSPaolo Bonzini #define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL)
7496b4c305cSPaolo Bonzini #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL)
7506b4c305cSPaolo Bonzini #define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL)
7516b4c305cSPaolo Bonzini #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
7526b4c305cSPaolo Bonzini 
7536b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
75488857acaSLaurent Vivier | Returns the fraction bits of the extended double-precision floating-point
75588857acaSLaurent Vivier | value `a'.
75688857acaSLaurent Vivier *----------------------------------------------------------------------------*/
75788857acaSLaurent Vivier 
75888857acaSLaurent Vivier static inline uint64_t extractFloatx80Frac(floatx80 a)
75988857acaSLaurent Vivier {
76088857acaSLaurent Vivier     return a.low;
76188857acaSLaurent Vivier }
76288857acaSLaurent Vivier 
76388857acaSLaurent Vivier /*----------------------------------------------------------------------------
76488857acaSLaurent Vivier | Returns the exponent bits of the extended double-precision floating-point
76588857acaSLaurent Vivier | value `a'.
76688857acaSLaurent Vivier *----------------------------------------------------------------------------*/
76788857acaSLaurent Vivier 
76888857acaSLaurent Vivier static inline int32_t extractFloatx80Exp(floatx80 a)
76988857acaSLaurent Vivier {
77088857acaSLaurent Vivier     return a.high & 0x7FFF;
77188857acaSLaurent Vivier }
77288857acaSLaurent Vivier 
77388857acaSLaurent Vivier /*----------------------------------------------------------------------------
77488857acaSLaurent Vivier | Returns the sign bit of the extended double-precision floating-point value
77588857acaSLaurent Vivier | `a'.
77688857acaSLaurent Vivier *----------------------------------------------------------------------------*/
77788857acaSLaurent Vivier 
77888857acaSLaurent Vivier static inline flag extractFloatx80Sign(floatx80 a)
77988857acaSLaurent Vivier {
78088857acaSLaurent Vivier     return a.high >> 15;
78188857acaSLaurent Vivier }
78288857acaSLaurent Vivier 
78388857acaSLaurent Vivier /*----------------------------------------------------------------------------
78488857acaSLaurent Vivier | Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
78588857acaSLaurent Vivier | extended double-precision floating-point value, returning the result.
78688857acaSLaurent Vivier *----------------------------------------------------------------------------*/
78788857acaSLaurent Vivier 
78888857acaSLaurent Vivier static inline floatx80 packFloatx80(flag zSign, int32_t zExp, uint64_t zSig)
78988857acaSLaurent Vivier {
79088857acaSLaurent Vivier     floatx80 z;
79188857acaSLaurent Vivier 
79288857acaSLaurent Vivier     z.low = zSig;
79388857acaSLaurent Vivier     z.high = (((uint16_t)zSign) << 15) + zExp;
79488857acaSLaurent Vivier     return z;
79588857acaSLaurent Vivier }
79688857acaSLaurent Vivier 
79788857acaSLaurent Vivier /*----------------------------------------------------------------------------
79888857acaSLaurent Vivier | Normalizes the subnormal extended double-precision floating-point value
79988857acaSLaurent Vivier | represented by the denormalized significand `aSig'.  The normalized exponent
80088857acaSLaurent Vivier | and significand are stored at the locations pointed to by `zExpPtr' and
80188857acaSLaurent Vivier | `zSigPtr', respectively.
80288857acaSLaurent Vivier *----------------------------------------------------------------------------*/
80388857acaSLaurent Vivier 
80488857acaSLaurent Vivier void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
80588857acaSLaurent Vivier                                 uint64_t *zSigPtr);
80688857acaSLaurent Vivier 
80788857acaSLaurent Vivier /*----------------------------------------------------------------------------
80888857acaSLaurent Vivier | Takes two extended double-precision floating-point values `a' and `b', one
80988857acaSLaurent Vivier | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
81088857acaSLaurent Vivier | `b' is a signaling NaN, the invalid exception is raised.
81188857acaSLaurent Vivier *----------------------------------------------------------------------------*/
81288857acaSLaurent Vivier 
81388857acaSLaurent Vivier floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status);
81488857acaSLaurent Vivier 
81588857acaSLaurent Vivier /*----------------------------------------------------------------------------
81688857acaSLaurent Vivier | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
81788857acaSLaurent Vivier | and extended significand formed by the concatenation of `zSig0' and `zSig1',
81888857acaSLaurent Vivier | and returns the proper extended double-precision floating-point value
81988857acaSLaurent Vivier | corresponding to the abstract input.  Ordinarily, the abstract value is
82088857acaSLaurent Vivier | rounded and packed into the extended double-precision format, with the
82188857acaSLaurent Vivier | inexact exception raised if the abstract input cannot be represented
82288857acaSLaurent Vivier | exactly.  However, if the abstract value is too large, the overflow and
82388857acaSLaurent Vivier | inexact exceptions are raised and an infinity or maximal finite value is
82488857acaSLaurent Vivier | returned.  If the abstract value is too small, the input value is rounded to
82588857acaSLaurent Vivier | a subnormal number, and the underflow and inexact exceptions are raised if
82688857acaSLaurent Vivier | the abstract input cannot be represented exactly as a subnormal extended
82788857acaSLaurent Vivier | double-precision floating-point number.
82888857acaSLaurent Vivier |     If `roundingPrecision' is 32 or 64, the result is rounded to the same
82988857acaSLaurent Vivier | number of bits as single or double precision, respectively.  Otherwise, the
83088857acaSLaurent Vivier | result is rounded to the full precision of the extended double-precision
83188857acaSLaurent Vivier | format.
83288857acaSLaurent Vivier |     The input significand must be normalized or smaller.  If the input
83388857acaSLaurent Vivier | significand is not normalized, `zExp' must be 0; in that case, the result
83488857acaSLaurent Vivier | returned is a subnormal number, and it must not require rounding.  The
83588857acaSLaurent Vivier | handling of underflow and overflow follows the IEC/IEEE Standard for Binary
83688857acaSLaurent Vivier | Floating-Point Arithmetic.
83788857acaSLaurent Vivier *----------------------------------------------------------------------------*/
83888857acaSLaurent Vivier 
83988857acaSLaurent Vivier floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
84088857acaSLaurent Vivier                               int32_t zExp, uint64_t zSig0, uint64_t zSig1,
84188857acaSLaurent Vivier                               float_status *status);
84288857acaSLaurent Vivier 
84388857acaSLaurent Vivier /*----------------------------------------------------------------------------
84488857acaSLaurent Vivier | Takes an abstract floating-point value having sign `zSign', exponent
84588857acaSLaurent Vivier | `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
84688857acaSLaurent Vivier | and returns the proper extended double-precision floating-point value
84788857acaSLaurent Vivier | corresponding to the abstract input.  This routine is just like
84888857acaSLaurent Vivier | `roundAndPackFloatx80' except that the input significand does not have to be
84988857acaSLaurent Vivier | normalized.
85088857acaSLaurent Vivier *----------------------------------------------------------------------------*/
85188857acaSLaurent Vivier 
85288857acaSLaurent Vivier floatx80 normalizeRoundAndPackFloatx80(int8_t roundingPrecision,
85388857acaSLaurent Vivier                                        flag zSign, int32_t zExp,
85488857acaSLaurent Vivier                                        uint64_t zSig0, uint64_t zSig1,
85588857acaSLaurent Vivier                                        float_status *status);
85688857acaSLaurent Vivier 
85788857acaSLaurent Vivier /*----------------------------------------------------------------------------
8586b4c305cSPaolo Bonzini | The pattern for a default generated extended double-precision NaN.
8596b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
860af39bc8cSAleksandar Markovic floatx80 floatx80_default_nan(float_status *status);
8616b4c305cSPaolo Bonzini 
8626b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
8636b4c305cSPaolo Bonzini | Software IEC/IEEE quadruple-precision conversion routines.
8646b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
865f4014512SPeter Maydell int32_t float128_to_int32(float128, float_status *status);
866f4014512SPeter Maydell int32_t float128_to_int32_round_to_zero(float128, float_status *status);
867f42c2224SPeter Maydell int64_t float128_to_int64(float128, float_status *status);
868f42c2224SPeter Maydell int64_t float128_to_int64_round_to_zero(float128, float_status *status);
8692e6d8568SBharata B Rao uint64_t float128_to_uint64(float128, float_status *status);
8702e6d8568SBharata B Rao uint64_t float128_to_uint64_round_to_zero(float128, float_status *status);
871fd425037SBharata B Rao uint32_t float128_to_uint32_round_to_zero(float128, float_status *status);
872e5a41ffaSPeter Maydell float32 float128_to_float32(float128, float_status *status);
873e5a41ffaSPeter Maydell float64 float128_to_float64(float128, float_status *status);
874e5a41ffaSPeter Maydell floatx80 float128_to_floatx80(float128, float_status *status);
8756b4c305cSPaolo Bonzini 
8766b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
8776b4c305cSPaolo Bonzini | Software IEC/IEEE quadruple-precision operations.
8786b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
879e5a41ffaSPeter Maydell float128 float128_round_to_int(float128, float_status *status);
880e5a41ffaSPeter Maydell float128 float128_add(float128, float128, float_status *status);
881e5a41ffaSPeter Maydell float128 float128_sub(float128, float128, float_status *status);
882e5a41ffaSPeter Maydell float128 float128_mul(float128, float128, float_status *status);
883e5a41ffaSPeter Maydell float128 float128_div(float128, float128, float_status *status);
884e5a41ffaSPeter Maydell float128 float128_rem(float128, float128, float_status *status);
885e5a41ffaSPeter Maydell float128 float128_sqrt(float128, float_status *status);
886e5a41ffaSPeter Maydell int float128_eq(float128, float128, float_status *status);
887e5a41ffaSPeter Maydell int float128_le(float128, float128, float_status *status);
888e5a41ffaSPeter Maydell int float128_lt(float128, float128, float_status *status);
889e5a41ffaSPeter Maydell int float128_unordered(float128, float128, float_status *status);
890e5a41ffaSPeter Maydell int float128_eq_quiet(float128, float128, float_status *status);
891e5a41ffaSPeter Maydell int float128_le_quiet(float128, float128, float_status *status);
892e5a41ffaSPeter Maydell int float128_lt_quiet(float128, float128, float_status *status);
893e5a41ffaSPeter Maydell int float128_unordered_quiet(float128, float128, float_status *status);
894e5a41ffaSPeter Maydell int float128_compare(float128, float128, float_status *status);
895e5a41ffaSPeter Maydell int float128_compare_quiet(float128, float128, float_status *status);
896af39bc8cSAleksandar Markovic int float128_is_quiet_nan(float128, float_status *status);
897af39bc8cSAleksandar Markovic int float128_is_signaling_nan(float128, float_status *status);
898d619bb98SRichard Henderson float128 float128_silence_nan(float128, float_status *status);
899e5a41ffaSPeter Maydell float128 float128_scalbn(float128, int, float_status *status);
9006b4c305cSPaolo Bonzini 
901a49db98dSLuiz Capitulino static inline float128 float128_abs(float128 a)
9026b4c305cSPaolo Bonzini {
9036b4c305cSPaolo Bonzini     a.high &= 0x7fffffffffffffffLL;
9046b4c305cSPaolo Bonzini     return a;
9056b4c305cSPaolo Bonzini }
9066b4c305cSPaolo Bonzini 
907a49db98dSLuiz Capitulino static inline float128 float128_chs(float128 a)
9086b4c305cSPaolo Bonzini {
9096b4c305cSPaolo Bonzini     a.high ^= 0x8000000000000000LL;
9106b4c305cSPaolo Bonzini     return a;
9116b4c305cSPaolo Bonzini }
9126b4c305cSPaolo Bonzini 
913a49db98dSLuiz Capitulino static inline int float128_is_infinity(float128 a)
9146b4c305cSPaolo Bonzini {
9156b4c305cSPaolo Bonzini     return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0;
9166b4c305cSPaolo Bonzini }
9176b4c305cSPaolo Bonzini 
918a49db98dSLuiz Capitulino static inline int float128_is_neg(float128 a)
9196b4c305cSPaolo Bonzini {
9206b4c305cSPaolo Bonzini     return a.high >> 63;
9216b4c305cSPaolo Bonzini }
9226b4c305cSPaolo Bonzini 
923a49db98dSLuiz Capitulino static inline int float128_is_zero(float128 a)
9246b4c305cSPaolo Bonzini {
9256b4c305cSPaolo Bonzini     return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
9266b4c305cSPaolo Bonzini }
9276b4c305cSPaolo Bonzini 
928a49db98dSLuiz Capitulino static inline int float128_is_zero_or_denormal(float128 a)
9296b4c305cSPaolo Bonzini {
9306b4c305cSPaolo Bonzini     return (a.high & 0x7fff000000000000LL) == 0;
9316b4c305cSPaolo Bonzini }
9326b4c305cSPaolo Bonzini 
933a49db98dSLuiz Capitulino static inline int float128_is_any_nan(float128 a)
9346b4c305cSPaolo Bonzini {
9356b4c305cSPaolo Bonzini     return ((a.high >> 48) & 0x7fff) == 0x7fff &&
9366b4c305cSPaolo Bonzini         ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0));
9376b4c305cSPaolo Bonzini }
9386b4c305cSPaolo Bonzini 
9391e397eadSRichard Henderson #define float128_zero make_float128(0, 0)
9401e397eadSRichard Henderson 
9416b4c305cSPaolo Bonzini /*----------------------------------------------------------------------------
9426b4c305cSPaolo Bonzini | The pattern for a default generated quadruple-precision NaN.
9436b4c305cSPaolo Bonzini *----------------------------------------------------------------------------*/
944af39bc8cSAleksandar Markovic float128 float128_default_nan(float_status *status);
9456b4c305cSPaolo Bonzini 
946175de524SMarkus Armbruster #endif /* SOFTFLOAT_H */
947