xref: /netbsd-src/sys/sys/ieee754.h (revision c795e5449dd63904752e7670b8d6d22782ac39f8)
1*c795e544Srillig /*	$NetBSD: ieee754.h,v 1.18 2024/05/12 10:34:56 rillig Exp $	*/
2a671ba71Skleink 
3a671ba71Skleink /*
4a671ba71Skleink  * Copyright (c) 1992, 1993
5a671ba71Skleink  *	The Regents of the University of California.  All rights reserved.
6a671ba71Skleink  *
7a671ba71Skleink  * This software was developed by the Computer Systems Engineering group
8a671ba71Skleink  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9a671ba71Skleink  * contributed to Berkeley.
10a671ba71Skleink  *
11a671ba71Skleink  * All advertising materials mentioning features or use of this software
12a671ba71Skleink  * must display the following acknowledgement:
13a671ba71Skleink  *	This product includes software developed by the University of
14a671ba71Skleink  *	California, Lawrence Berkeley Laboratory.
15a671ba71Skleink  *
16a671ba71Skleink  * Redistribution and use in source and binary forms, with or without
17a671ba71Skleink  * modification, are permitted provided that the following conditions
18a671ba71Skleink  * are met:
19a671ba71Skleink  * 1. Redistributions of source code must retain the above copyright
20a671ba71Skleink  *    notice, this list of conditions and the following disclaimer.
21a671ba71Skleink  * 2. Redistributions in binary form must reproduce the above copyright
22a671ba71Skleink  *    notice, this list of conditions and the following disclaimer in the
23a671ba71Skleink  *    documentation and/or other materials provided with the distribution.
24a671ba71Skleink  * 3. Neither the name of the University nor the names of its contributors
25a671ba71Skleink  *    may be used to endorse or promote products derived from this software
26a671ba71Skleink  *    without specific prior written permission.
27a671ba71Skleink  *
28a671ba71Skleink  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29a671ba71Skleink  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30a671ba71Skleink  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31a671ba71Skleink  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32a671ba71Skleink  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33a671ba71Skleink  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34a671ba71Skleink  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35a671ba71Skleink  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36a671ba71Skleink  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37a671ba71Skleink  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38a671ba71Skleink  * SUCH DAMAGE.
39a671ba71Skleink  *
40a671ba71Skleink  *	@(#)ieee.h	8.1 (Berkeley) 6/11/93
41a671ba71Skleink  */
42a563f6baSchristos #ifndef _SYS_IEEE754_H_
43a563f6baSchristos #define _SYS_IEEE754_H_
44a671ba71Skleink 
45a671ba71Skleink /*
46a671ba71Skleink  * NOTICE: This is not a standalone file.  To use it, #include it in
47a671ba71Skleink  * your port's ieee.h header.
48a671ba71Skleink  */
49a671ba71Skleink 
50a671ba71Skleink #include <machine/endian.h>
51a671ba71Skleink 
52a671ba71Skleink /*
53a671ba71Skleink  * <sys/ieee754.h> defines the layout of IEEE 754 floating point types.
54a671ba71Skleink  * Only single-precision and double-precision types are defined here;
55b526449aSchristos  * 128-bit long doubles are defined here IFF __HAVE_LONG_DOUBLE equals 128.
564d035bbcSmatt  * Otherwise extended types, if available, are defined in the machine-dependent
57a671ba71Skleink  * header.
58a671ba71Skleink  */
59a671ba71Skleink 
60a671ba71Skleink /*
61a671ba71Skleink  * Define the number of bits in each fraction and exponent.
62a671ba71Skleink  *
63a671ba71Skleink  *		     k	         k+1
64a671ba71Skleink  * Note that  1.0 x 2  == 0.1 x 2      and that denorms are represented
65a671ba71Skleink  *
66a671ba71Skleink  *					  (-exp_bias+1)
67a671ba71Skleink  * as fractions that look like 0.fffff x 2             .  This means that
68a671ba71Skleink  *
69a671ba71Skleink  *			 -126
70a671ba71Skleink  * the number 0.10000 x 2    , for instance, is the same as the normalized
71a671ba71Skleink  *
72a671ba71Skleink  *		-127			   -128
73a671ba71Skleink  * float 1.0 x 2    .  Thus, to represent 2    , we need one leading zero
74a671ba71Skleink  *
75a671ba71Skleink  *				  -129
76a671ba71Skleink  * in the fraction; to represent 2    , we need two, and so on.  This
77a671ba71Skleink  *
78a671ba71Skleink  *						     (-exp_bias-fracbits+1)
79a671ba71Skleink  * implies that the smallest denormalized number is 2
80a671ba71Skleink  *
81a671ba71Skleink  * for whichever format we are talking about: for single precision, for
82a671ba71Skleink  *
83a671ba71Skleink  *						-126		-149
84a671ba71Skleink  * instance, we get .00000000000000000000001 x 2    , or 1.0 x 2    , and
85a671ba71Skleink  *
86a671ba71Skleink  * -149 == -127 - 23 + 1.
87a671ba71Skleink  */
88a671ba71Skleink #define	SNG_EXPBITS	8
89a671ba71Skleink #define	SNG_FRACBITS	23
90a671ba71Skleink 
91a671ba71Skleink struct ieee_single {
92ecb9893bSsimonb #if _BYTE_ORDER == _BIG_ENDIAN
93710c9c26Sdholland 	unsigned int	sng_sign:1;
94710c9c26Sdholland 	unsigned int	sng_exp:SNG_EXPBITS;
95710c9c26Sdholland 	unsigned int	sng_frac:SNG_FRACBITS;
96a671ba71Skleink #else
97710c9c26Sdholland 	unsigned int	sng_frac:SNG_FRACBITS;
98710c9c26Sdholland 	unsigned int	sng_exp:SNG_EXPBITS;
99710c9c26Sdholland 	unsigned int	sng_sign:1;
100a671ba71Skleink #endif
101a671ba71Skleink };
102a671ba71Skleink 
103efdcbc42Schristos #define	DBL_EXPBITS	11
104efdcbc42Schristos #define	DBL_FRACHBITS	20
105efdcbc42Schristos #define	DBL_FRACLBITS	32
106efdcbc42Schristos #define	DBL_FRACBITS	(DBL_FRACHBITS + DBL_FRACLBITS)
107efdcbc42Schristos 
108a671ba71Skleink struct ieee_double {
109ecb9893bSsimonb #if _BYTE_ORDER == _BIG_ENDIAN
110710c9c26Sdholland 	unsigned int	dbl_sign:1;
111710c9c26Sdholland 	unsigned int	dbl_exp:DBL_EXPBITS;
112710c9c26Sdholland 	unsigned int	dbl_frach:DBL_FRACHBITS;
113710c9c26Sdholland 	unsigned int	dbl_fracl:DBL_FRACLBITS;
114a671ba71Skleink #else
115710c9c26Sdholland 	unsigned int	dbl_fracl:DBL_FRACLBITS;
116710c9c26Sdholland 	unsigned int	dbl_frach:DBL_FRACHBITS;
117710c9c26Sdholland 	unsigned int	dbl_exp:DBL_EXPBITS;
118710c9c26Sdholland 	unsigned int	dbl_sign:1;
119a671ba71Skleink #endif
120a671ba71Skleink };
121a671ba71Skleink 
122450a706eSmatt #if __HAVE_LONG_DOUBLE + 0 == 128
123450a706eSmatt 
1244d035bbcSmatt #define	EXT_EXPBITS	15
1254d035bbcSmatt #define EXT_FRACHBITS	48
1264d035bbcSmatt #define	EXT_FRACLBITS	64
1274d035bbcSmatt #define	EXT_FRACBITS	(EXT_FRACLBITS + EXT_FRACHBITS)
1284d035bbcSmatt 
1294d035bbcSmatt #define	EXT_TO_ARRAY32(u, a) do {				\
1304d035bbcSmatt 	(a)[0] = (uint32_t)((u).extu_ext.ext_fracl >>  0);	\
1314d035bbcSmatt 	(a)[1] = (uint32_t)((u).extu_ext.ext_fracl >> 32);	\
1324d035bbcSmatt 	(a)[2] = (uint32_t)((u).extu_ext.ext_frach >>  0);	\
1334d035bbcSmatt 	(a)[3] = (uint32_t)((u).extu_ext.ext_frach >> 32);	\
134*c795e544Srillig } while (0)
1354d035bbcSmatt 
1364d035bbcSmatt struct ieee_ext {
1374d035bbcSmatt #if _BYTE_ORDER == _BIG_ENDIAN
1384d035bbcSmatt 	uint64_t ext_sign:1;
1394d035bbcSmatt 	uint64_t ext_exp:EXT_EXPBITS;
1404d035bbcSmatt 	uint64_t ext_frach:EXT_FRACHBITS;
1414d035bbcSmatt 	uint64_t ext_fracl;
1424d035bbcSmatt #else
1434d035bbcSmatt 	uint64_t ext_fracl;
1444d035bbcSmatt 	uint64_t ext_frach:EXT_FRACHBITS;
1454d035bbcSmatt 	uint64_t ext_exp:EXT_EXPBITS;
1464d035bbcSmatt 	uint64_t ext_sign:1;
1474d035bbcSmatt #endif
1484d035bbcSmatt };
1494d035bbcSmatt #endif /* __HAVE_LONG_DOUBLE == 128 */
1504d035bbcSmatt 
151a671ba71Skleink /*
152a671ba71Skleink  * Floats whose exponent is in [1..INFNAN) (of whatever type) are
153a671ba71Skleink  * `normal'.  Floats whose exponent is INFNAN are either Inf or NaN.
154a671ba71Skleink  * Floats whose exponent is zero are either zero (iff all fraction
155a671ba71Skleink  * bits are zero) or subnormal values.
156a671ba71Skleink  *
157b2cb7fcdSkleink  * At least one `signalling NaN' and one `quiet NaN' value must be
158b2cb7fcdSkleink  * implemented.  It is left to the architecture to specify how to
159b2cb7fcdSkleink  * distinguish between these.
160a671ba71Skleink  */
161a671ba71Skleink #define	SNG_EXP_INFNAN	255
162a671ba71Skleink #define	DBL_EXP_INFNAN	2047
163a5e6c1dbSmatt #if __HAVE_LONG_DOUBLE + 0 == 128
1644d035bbcSmatt #define	EXT_EXP_INFNAN	0x7fff
165a5e6c1dbSmatt #endif
166a671ba71Skleink 
167a671ba71Skleink /*
168a671ba71Skleink  * Exponent biases.
169a671ba71Skleink  */
170a671ba71Skleink #define	SNG_EXP_BIAS	127
171a671ba71Skleink #define	DBL_EXP_BIAS	1023
172a5e6c1dbSmatt #if __HAVE_LONG_DOUBLE + 0 == 128
1734d035bbcSmatt #define	EXT_EXP_BIAS	16383
174a5e6c1dbSmatt #endif
175b37192f0Skleink 
176b37192f0Skleink /*
177b37192f0Skleink  * Convenience data structures.
178b37192f0Skleink  */
179b37192f0Skleink union ieee_single_u {
180b37192f0Skleink 	float			sngu_f;
181964d6747Skleink 	struct ieee_single	sngu_sng;
182b37192f0Skleink };
183b37192f0Skleink 
18463aca31dSmatt #define	sngu_sign	sngu_sng.sng_sign
18563aca31dSmatt #define	sngu_exp	sngu_sng.sng_exp
18663aca31dSmatt #define	sngu_frac	sngu_sng.sng_frac
18789ffffc8Smatt #define	SNGU_ZEROFRAC_P(u)	((u).sngu_frac != 0)
18863aca31dSmatt 
189b37192f0Skleink union ieee_double_u {
190b37192f0Skleink 	double			dblu_d;
191b37192f0Skleink 	struct ieee_double	dblu_dbl;
192b37192f0Skleink };
19363aca31dSmatt 
19463aca31dSmatt #define	dblu_sign	dblu_dbl.dbl_sign
19563aca31dSmatt #define	dblu_exp	dblu_dbl.dbl_exp
19663aca31dSmatt #define	dblu_frach	dblu_dbl.dbl_frach
19763aca31dSmatt #define	dblu_fracl	dblu_dbl.dbl_fracl
19889ffffc8Smatt #define	DBLU_ZEROFRAC_P(u)	(((u).dblu_frach|(u).dblu_fracl) != 0)
19989ffffc8Smatt 
200facaf331Smatt #if __HAVE_LONG_DOUBLE + 0 == 128
2014d035bbcSmatt union ieee_ext_u {
2024d035bbcSmatt 	long double		extu_ld;
2034d035bbcSmatt 	struct ieee_ext		extu_ext;
2044d035bbcSmatt };
2054d035bbcSmatt 
2064d035bbcSmatt #define extu_exp	extu_ext.ext_exp
2074d035bbcSmatt #define extu_sign	extu_ext.ext_sign
2084d035bbcSmatt #define extu_fracl	extu_ext.ext_fracl
2094d035bbcSmatt #define extu_frach	extu_ext.ext_frach
2104d035bbcSmatt #define	EXTU_ZEROFRAC_P(u)	(((u).extu_frach|(u).extu_fracl) != 0)
2114d035bbcSmatt 
2124d035bbcSmatt #ifndef LDBL_NBIT
2134d035bbcSmatt #define LDBL_IMPLICIT_NBIT	1	/* our NBIT is implicit */
2144d035bbcSmatt #endif
2154d035bbcSmatt 
2164d035bbcSmatt #endif /* __HAVE_LONG_DOUBLE */
2174d035bbcSmatt 
218a563f6baSchristos #endif /* _SYS_IEEE754_H_ */
219