xref: /netbsd-src/sys/lib/libkern/softfloat.h (revision e450f2e45d724b0ec51c4cff35a6f0592db866ac)
1*e450f2e4Sthorpej /* $NetBSD: softfloat.h,v 1.6 2020/09/02 03:41:56 thorpej Exp $ */
22df695b1Sross 
32df695b1Sross /* This is a derivative work. */
42df695b1Sross 
52df695b1Sross /*-
62df695b1Sross  * Copyright (c) 2001 The NetBSD Foundation, Inc.
72df695b1Sross  * All rights reserved.
82df695b1Sross  *
92df695b1Sross  * This code is derived from software contributed to The NetBSD Foundation
102df695b1Sross  * by Ross Harvey.
112df695b1Sross  *
122df695b1Sross  * Redistribution and use in source and binary forms, with or without
132df695b1Sross  * modification, are permitted provided that the following conditions
142df695b1Sross  * are met:
152df695b1Sross  * 1. Redistributions of source code must retain the above copyright
162df695b1Sross  *    notice, this list of conditions and the following disclaimer.
172df695b1Sross  * 2. Redistributions in binary form must reproduce the above copyright
182df695b1Sross  *    notice, this list of conditions and the following disclaimer in the
192df695b1Sross  *    documentation and/or other materials provided with the distribution.
202df695b1Sross  *
212df695b1Sross  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
222df695b1Sross  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
232df695b1Sross  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
242df695b1Sross  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
252df695b1Sross  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
262df695b1Sross  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
272df695b1Sross  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
282df695b1Sross  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
292df695b1Sross  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
302df695b1Sross  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
312df695b1Sross  * POSSIBILITY OF SUCH DAMAGE.
322df695b1Sross  */
332df695b1Sross 
34*e450f2e4Sthorpej /*============================================================================
352df695b1Sross 
36*e450f2e4Sthorpej This C header file template is part of the Berkeley SoftFloat IEEE Floating-
37*e450f2e4Sthorpej Point Arithmetic Package, Release 2c, by John R. Hauser.
382df695b1Sross 
39*e450f2e4Sthorpej THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
40*e450f2e4Sthorpej been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
41*e450f2e4Sthorpej RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
42*e450f2e4Sthorpej AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR OTHER
43*e450f2e4Sthorpej PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR
44*e450f2e4Sthorpej THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE EFFECTIVELY
45*e450f2e4Sthorpej INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE
46*e450f2e4Sthorpej (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR OTHER
47*e450f2e4Sthorpej PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, OR
48*e450f2e4Sthorpej INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF THE
49*e450f2e4Sthorpej SOFTWARE.
502df695b1Sross 
51*e450f2e4Sthorpej Derivative works require also that (1) the source code for the derivative work
52*e450f2e4Sthorpej includes prominent notice that the work is derivative, and (2) the source code
53*e450f2e4Sthorpej includes prominent notice of these three paragraphs for those parts of this
54*e450f2e4Sthorpej code that are retained.
552df695b1Sross 
56*e450f2e4Sthorpej =============================================================================*/
572df695b1Sross 
582df695b1Sross #include <sys/types.h>
592df695b1Sross 
602df695b1Sross #if !defined(_KERNEL) && !defined(_STANDALONE)
612df695b1Sross #include <inttypes.h>
622df695b1Sross #include <ieeefp.h>
632df695b1Sross #else
642df695b1Sross #include "sys/inttypes.h"
652df695b1Sross #include "machine/ieeefp.h"
662df695b1Sross #endif
672df695b1Sross #include <sys/endian.h>
682df695b1Sross 
69*e450f2e4Sthorpej /*----------------------------------------------------------------------------
70*e450f2e4Sthorpej | The macro `FLOATX80' must be defined to enable the double-extended-precision
71*e450f2e4Sthorpej | floating-point format `floatx80'.  If this macro is not defined, the
72*e450f2e4Sthorpej | `floatx80' type will not be defined, and none of the functions that either
73*e450f2e4Sthorpej | input or output the `floatx80' type will be defined.  The same applies to
74*e450f2e4Sthorpej | the `FLOAT128' macro and the quadruple-precision format `float128'.
75*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
762df695b1Sross /* #define FLOATX80 */
772df695b1Sross /* #define FLOAT128 */
782df695b1Sross 
79*e450f2e4Sthorpej /*----------------------------------------------------------------------------
80*e450f2e4Sthorpej | Software IEEE floating-point types.
81*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
822df695b1Sross typedef u_int32_t float32;
832df695b1Sross typedef u_int64_t float64;
842df695b1Sross #ifdef FLOATX80
852df695b1Sross typedef struct {
862df695b1Sross #if BYTE_ORDER == BIG_ENDIAN
872df695b1Sross     u_int16_t high;
882df695b1Sross     u_int64_t low;
892df695b1Sross #else
902df695b1Sross     u_int64_t low;
912df695b1Sross     u_int16_t high;
922df695b1Sross #endif
932df695b1Sross } floatx80;
942df695b1Sross #endif
952df695b1Sross #ifdef FLOAT128
962df695b1Sross typedef struct {
972df695b1Sross     u_int64_t high, low;
982df695b1Sross } float128;
992df695b1Sross #endif
1002df695b1Sross 
1012df695b1Sross /*
1022df695b1Sross  * Some of the global variables that used to be here have been removed for
1032df695b1Sross  * fairly obvious (defopt-MULTIPROCESSOR) reasons.  The rest (which don't
1042df695b1Sross  * change dynamically) will be removed later. [ross]
1052df695b1Sross  */
1062df695b1Sross 
1072df695b1Sross #define float_rounding_mode() fpgetround()
1082df695b1Sross 
109*e450f2e4Sthorpej /*----------------------------------------------------------------------------
110*e450f2e4Sthorpej | Software IEEE floating-point underflow tininess-detection mode.
111*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
1122df695b1Sross extern int float_detect_tininess;
1132df695b1Sross enum {
1142df695b1Sross     float_tininess_after_rounding  = 1,
1152df695b1Sross     float_tininess_before_rounding = 0
1162df695b1Sross };
1172df695b1Sross 
118*e450f2e4Sthorpej /*----------------------------------------------------------------------------
119*e450f2e4Sthorpej | Software IEEE floating-point rounding mode.
120*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
1212df695b1Sross enum {
1222df695b1Sross     float_round_nearest_even = FP_RN,
1232df695b1Sross     float_round_to_zero      = FP_RZ,
1242df695b1Sross     float_round_down         = FP_RM,
1252df695b1Sross     float_round_up           = FP_RP
1262df695b1Sross };
1272df695b1Sross 
128*e450f2e4Sthorpej /*----------------------------------------------------------------------------
129*e450f2e4Sthorpej | Software IEEE floating-point exception flags.
130*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
1312df695b1Sross enum {
1322df695b1Sross     float_flag_inexact   =  FP_X_IMP,
1332df695b1Sross     float_flag_underflow =  FP_X_UFL,
1342df695b1Sross     float_flag_overflow  =  FP_X_OFL,
1352df695b1Sross     float_flag_divbyzero =  FP_X_DZ,
1362df695b1Sross     float_flag_invalid   =  FP_X_INV
1372df695b1Sross };
1382df695b1Sross 
139*e450f2e4Sthorpej /*----------------------------------------------------------------------------
140*e450f2e4Sthorpej | Routine to raise any or all of the software IEEE floating-point exception
141*e450f2e4Sthorpej | flags.
142*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
1432df695b1Sross /*
144*e450f2e4Sthorpej  * Routines provided by <machine/ieeefp.h>:
145*e450f2e4Sthorpej  *
146*e450f2e4Sthorpej  * float_raise()
147*e450f2e4Sthorpej  * float_set_inexact()
148*e450f2e4Sthorpej  * float_set_invalid()
1492df695b1Sross  */
150*e450f2e4Sthorpej 
151*e450f2e4Sthorpej /*----------------------------------------------------------------------------
152*e450f2e4Sthorpej | Software IEEE integer-to-floating-point conversion routines.
153*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
1542df695b1Sross float32 int32_to_float32( int );
1552df695b1Sross float64 int32_to_float64( int );
1562df695b1Sross #ifdef FLOATX80
1572df695b1Sross floatx80 int32_to_floatx80( int );
1582df695b1Sross #endif
1592df695b1Sross #ifdef FLOAT128
1602df695b1Sross float128 int32_to_float128( int );
1612df695b1Sross #endif
1622df695b1Sross #ifndef SOFTFLOAT_FOR_GCC /* __floatdi?f is in libgcc2.c */
1632df695b1Sross float32 int64_to_float32( int64_t );
1642df695b1Sross float64 int64_to_float64( int64_t );
1652df695b1Sross #ifdef FLOATX80
1662df695b1Sross floatx80 int64_to_floatx80( int64_t );
1672df695b1Sross #endif
1682df695b1Sross #ifdef FLOAT128
1692df695b1Sross float128 int64_to_float128( int64_t );
1702df695b1Sross #endif
1712df695b1Sross #endif
1722df695b1Sross 
173*e450f2e4Sthorpej /*----------------------------------------------------------------------------
174*e450f2e4Sthorpej | Software IEEE single-precision conversion routines.
175*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
1762df695b1Sross int float32_to_int32( float32 );
1772df695b1Sross int float32_to_int32_round_to_zero( float32 );
1782df695b1Sross #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */
1792df695b1Sross int64_t float32_to_int64( float32 );
1802df695b1Sross int64_t float32_to_int64_round_to_zero( float32 );
1812df695b1Sross #endif
1822df695b1Sross float64 float32_to_float64( float32 );
1832df695b1Sross #ifdef FLOATX80
1842df695b1Sross floatx80 float32_to_floatx80( float32 );
1852df695b1Sross #endif
1862df695b1Sross #ifdef FLOAT128
1872df695b1Sross float128 float32_to_float128( float32 );
1882df695b1Sross #endif
1892df695b1Sross 
190*e450f2e4Sthorpej /*----------------------------------------------------------------------------
191*e450f2e4Sthorpej | Software IEEE single-precision operations.
192*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
1932df695b1Sross float32 float32_round_to_int( float32 );
1942df695b1Sross float32 float32_add( float32, float32 );
1952df695b1Sross float32 float32_sub( float32, float32 );
1962df695b1Sross float32 float32_mul( float32, float32 );
1972df695b1Sross float32 float32_div( float32, float32 );
1982df695b1Sross float32 float32_rem( float32, float32 );
1992df695b1Sross float32 float32_sqrt( float32 );
2002df695b1Sross int float32_eq( float32, float32 );
2012df695b1Sross int float32_le( float32, float32 );
2022df695b1Sross int float32_lt( float32, float32 );
2032df695b1Sross int float32_eq_signaling( float32, float32 );
2042df695b1Sross int float32_le_quiet( float32, float32 );
2052df695b1Sross int float32_lt_quiet( float32, float32 );
2062df695b1Sross #ifndef SOFTFLOAT_FOR_GCC
2072df695b1Sross int float32_is_signaling_nan( float32 );
2082df695b1Sross #endif
2092df695b1Sross 
210*e450f2e4Sthorpej /*----------------------------------------------------------------------------
211*e450f2e4Sthorpej | Software IEEE double-precision conversion routines.
212*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
2132df695b1Sross int float64_to_int32( float64 );
2142df695b1Sross int float64_to_int32_round_to_zero( float64 );
2152df695b1Sross #ifndef SOFTFLOAT_FOR_GCC /* __fix?fdi provided by libgcc2.c */
2162df695b1Sross int64_t float64_to_int64( float64 );
217c9526096Smartin uint64_t float64_to_uint64( float64 );
2182df695b1Sross int64_t float64_to_int64_round_to_zero( float64 );
2192df695b1Sross #endif
2202df695b1Sross float32 float64_to_float32( float64 );
2212df695b1Sross #ifdef FLOATX80
2222df695b1Sross floatx80 float64_to_floatx80( float64 );
2232df695b1Sross #endif
2242df695b1Sross #ifdef FLOAT128
2252df695b1Sross float128 float64_to_float128( float64 );
2262df695b1Sross #endif
2272df695b1Sross 
228*e450f2e4Sthorpej /*----------------------------------------------------------------------------
229*e450f2e4Sthorpej | Software IEEE double-precision operations.
230*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
231*e450f2e4Sthorpej 
232*e450f2e4Sthorpej /*----------------------------------------------------------------------------
233*e450f2e4Sthorpej | The pattern for a default generated double-precision NaN.
234*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
2352df695b1Sross #define float64_default_nan 0xFFF8000000000000LL
2362df695b1Sross 
237*e450f2e4Sthorpej /*----------------------------------------------------------------------------
238*e450f2e4Sthorpej | Returns 1 if the double-precision floating-point value `a' is a NaN;
239*e450f2e4Sthorpej | otherwise returns 0.
240*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
241*e450f2e4Sthorpej 
242fbae48b9Sperry static __inline int
float64_is_nan(float64 a)2432df695b1Sross float64_is_nan(float64 a)
2442df695b1Sross {
2452df695b1Sross 	return 0xFFE0000000000000LL < a << 1;
2462df695b1Sross }
2472df695b1Sross 
248*e450f2e4Sthorpej /*----------------------------------------------------------------------------
249*e450f2e4Sthorpej | Returns 1 if the double-precision floating-point value `a' is a signaling
250*e450f2e4Sthorpej | NaN; otherwise returns 0.
251*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
252*e450f2e4Sthorpej 
253fbae48b9Sperry static __inline int
float64_is_signaling_nan(float64 a)2542df695b1Sross float64_is_signaling_nan(float64 a)
2552df695b1Sross {
2562df695b1Sross 	return (a >> 51 & 0xFFF) == 0xFFE && (a & 0x0007FFFFFFFFFFFFLL);
2572df695b1Sross }
2582df695b1Sross 
2592df695b1Sross float64 float64_round_to_int( float64 );
2602df695b1Sross float64 float64_add( float64, float64 );
2612df695b1Sross float64 float64_sub( float64, float64 );
2622df695b1Sross float64 float64_mul( float64, float64 );
2632df695b1Sross float64 float64_div( float64, float64 );
2642df695b1Sross float64 float64_rem( float64, float64 );
2652df695b1Sross float64 float64_sqrt( float64 );
2662df695b1Sross int float64_eq( float64, float64 );
2672df695b1Sross int float64_le( float64, float64 );
2682df695b1Sross int float64_lt( float64, float64 );
2692df695b1Sross int float64_eq_signaling( float64, float64 );
2702df695b1Sross int float64_le_quiet( float64, float64 );
2712df695b1Sross int float64_lt_quiet( float64, float64 );
2722df695b1Sross #ifndef SOFTFLOAT_FOR_GCC
2732df695b1Sross int float64_is_signaling_nan( float64 );
2742df695b1Sross #endif
2752df695b1Sross 
2762df695b1Sross #ifdef FLOATX80
2772df695b1Sross 
278*e450f2e4Sthorpej /*----------------------------------------------------------------------------
279*e450f2e4Sthorpej | Software IEEE double-extended-precision conversion routines.
280*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
2812df695b1Sross int floatx80_to_int32( floatx80 );
2822df695b1Sross int floatx80_to_int32_round_to_zero( floatx80 );
2832df695b1Sross int64_t floatx80_to_int64( floatx80 );
2842df695b1Sross int64_t floatx80_to_int64_round_to_zero( floatx80 );
2852df695b1Sross float32 floatx80_to_float32( floatx80 );
2862df695b1Sross float64 floatx80_to_float64( floatx80 );
2872df695b1Sross #ifdef FLOAT128
2882df695b1Sross float128 floatx80_to_float128( floatx80 );
2892df695b1Sross #endif
2902df695b1Sross 
291*e450f2e4Sthorpej /*----------------------------------------------------------------------------
292*e450f2e4Sthorpej | Software IEEE double-extended-precision rounding precision.  Valid values
293*e450f2e4Sthorpej | are 32, 64, and 80.
294*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
2952df695b1Sross extern int floatx80_rounding_precision;
2962df695b1Sross 
297*e450f2e4Sthorpej /*----------------------------------------------------------------------------
298*e450f2e4Sthorpej | Software IEEE double-extended-precision operations.
299*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
3002df695b1Sross floatx80 floatx80_round_to_int( floatx80 );
3012df695b1Sross floatx80 floatx80_add( floatx80, floatx80 );
3022df695b1Sross floatx80 floatx80_sub( floatx80, floatx80 );
3032df695b1Sross floatx80 floatx80_mul( floatx80, floatx80 );
3042df695b1Sross floatx80 floatx80_div( floatx80, floatx80 );
3052df695b1Sross floatx80 floatx80_rem( floatx80, floatx80 );
3062df695b1Sross floatx80 floatx80_sqrt( floatx80 );
3072df695b1Sross int floatx80_eq( floatx80, floatx80 );
3082df695b1Sross int floatx80_le( floatx80, floatx80 );
3092df695b1Sross int floatx80_lt( floatx80, floatx80 );
3102df695b1Sross int floatx80_eq_signaling( floatx80, floatx80 );
3112df695b1Sross int floatx80_le_quiet( floatx80, floatx80 );
3122df695b1Sross int floatx80_lt_quiet( floatx80, floatx80 );
3132df695b1Sross int floatx80_is_signaling_nan( floatx80 );
3142df695b1Sross 
3152df695b1Sross #endif
3162df695b1Sross 
3172df695b1Sross #ifdef FLOAT128
3182df695b1Sross 
319*e450f2e4Sthorpej /*----------------------------------------------------------------------------
320*e450f2e4Sthorpej | Software IEEE quadruple-precision conversion routines.
321*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
3222df695b1Sross int float128_to_int32( float128 );
3232df695b1Sross int float128_to_int32_round_to_zero( float128 );
3242df695b1Sross int64_t float128_to_int64( float128 );
3252df695b1Sross int64_t float128_to_int64_round_to_zero( float128 );
3262df695b1Sross float32 float128_to_float32( float128 );
3272df695b1Sross float64 float128_to_float64( float128 );
3282df695b1Sross #ifdef FLOATX80
3292df695b1Sross floatx80 float128_to_floatx80( float128 );
3302df695b1Sross #endif
3312df695b1Sross 
332*e450f2e4Sthorpej /*----------------------------------------------------------------------------
333*e450f2e4Sthorpej | Software IEEE quadruple-precision operations.
334*e450f2e4Sthorpej *----------------------------------------------------------------------------*/
3352df695b1Sross float128 float128_round_to_int( float128 );
3362df695b1Sross float128 float128_add( float128, float128 );
3372df695b1Sross float128 float128_sub( float128, float128 );
3382df695b1Sross float128 float128_mul( float128, float128 );
3392df695b1Sross float128 float128_div( float128, float128 );
3402df695b1Sross float128 float128_rem( float128, float128 );
3412df695b1Sross float128 float128_sqrt( float128 );
3422df695b1Sross int float128_eq( float128, float128 );
3432df695b1Sross int float128_le( float128, float128 );
3442df695b1Sross int float128_lt( float128, float128 );
3452df695b1Sross int float128_eq_signaling( float128, float128 );
3462df695b1Sross int float128_le_quiet( float128, float128 );
3472df695b1Sross int float128_lt_quiet( float128, float128 );
3482df695b1Sross int float128_is_signaling_nan( float128 );
3492df695b1Sross 
3502df695b1Sross #endif
3512df695b1Sross 
352