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