1 /* Copyright (C) 1992-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #ifndef _IEEE754_H
19 #define _IEEE754_H 1
20 
21 #include <features.h>
22 
23 #include <bits/endian.h>
24 #include <bits/floatn.h>
25 
26 __BEGIN_DECLS
27 
28 union ieee754_float
29   {
30     float f;
31 
32     /* This is the IEEE 754 single-precision format.  */
33     struct
34       {
35 #if	__BYTE_ORDER == __BIG_ENDIAN
36 	unsigned int negative:1;
37 	unsigned int exponent:8;
38 	unsigned int mantissa:23;
39 #endif				/* Big endian.  */
40 #if	__BYTE_ORDER == __LITTLE_ENDIAN
41 	unsigned int mantissa:23;
42 	unsigned int exponent:8;
43 	unsigned int negative:1;
44 #endif				/* Little endian.  */
45       } ieee;
46 
47     /* This format makes it easier to see if a NaN is a signalling NaN.  */
48     struct
49       {
50 #if	__BYTE_ORDER == __BIG_ENDIAN
51 	unsigned int negative:1;
52 	unsigned int exponent:8;
53 	unsigned int quiet_nan:1;
54 	unsigned int mantissa:22;
55 #endif				/* Big endian.  */
56 #if	__BYTE_ORDER == __LITTLE_ENDIAN
57 	unsigned int mantissa:22;
58 	unsigned int quiet_nan:1;
59 	unsigned int exponent:8;
60 	unsigned int negative:1;
61 #endif				/* Little endian.  */
62       } ieee_nan;
63   };
64 
65 #define IEEE754_FLOAT_BIAS	0x7f /* Added to exponent.  */
66 
67 
68 union ieee754_double
69   {
70     double d;
71 
72     /* This is the IEEE 754 double-precision format.  */
73     struct
74       {
75 #if	__BYTE_ORDER == __BIG_ENDIAN
76 	unsigned int negative:1;
77 	unsigned int exponent:11;
78 	/* Together these comprise the mantissa.  */
79 	unsigned int mantissa0:20;
80 	unsigned int mantissa1:32;
81 #endif				/* Big endian.  */
82 #if	__BYTE_ORDER == __LITTLE_ENDIAN
83 	/* Together these comprise the mantissa.  */
84 	unsigned int mantissa1:32;
85 	unsigned int mantissa0:20;
86 	unsigned int exponent:11;
87 	unsigned int negative:1;
88 #endif				/* Little endian.  */
89       } ieee;
90 
91     /* This format makes it easier to see if a NaN is a signalling NaN.  */
92     struct
93       {
94 #if	__BYTE_ORDER == __BIG_ENDIAN
95 	unsigned int negative:1;
96 	unsigned int exponent:11;
97 	unsigned int quiet_nan:1;
98 	/* Together these comprise the mantissa.  */
99 	unsigned int mantissa0:19;
100 	unsigned int mantissa1:32;
101 #else
102 	/* Together these comprise the mantissa.  */
103 	unsigned int mantissa1:32;
104 	unsigned int mantissa0:19;
105 	unsigned int quiet_nan:1;
106 	unsigned int exponent:11;
107 	unsigned int negative:1;
108 #endif
109       } ieee_nan;
110   };
111 
112 #define IEEE754_DOUBLE_BIAS	0x3ff /* Added to exponent.  */
113 
114 
115 #if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
116 /* long double is IEEE 128 bit */
117 union ieee854_long_double
118   {
119     long double d;
120 
121     /* This is the IEEE 854 quad-precision format.  */
122     struct
123       {
124 #if	__BYTE_ORDER == __BIG_ENDIAN
125 	unsigned int negative:1;
126 	unsigned int exponent:15;
127 	/* Together these comprise the mantissa.  */
128 	unsigned int mantissa0:16;
129 	unsigned int mantissa1:32;
130 	unsigned int mantissa2:32;
131 	unsigned int mantissa3:32;
132 #endif				/* Big endian.  */
133 #if	__BYTE_ORDER == __LITTLE_ENDIAN
134 	/* Together these comprise the mantissa.  */
135 	unsigned int mantissa3:32;
136 	unsigned int mantissa2:32;
137 	unsigned int mantissa1:32;
138 	unsigned int mantissa0:16;
139 	unsigned int exponent:15;
140 	unsigned int negative:1;
141 #endif				/* Little endian.  */
142       } ieee;
143 
144     /* This format makes it easier to see if a NaN is a signalling NaN.  */
145     struct
146       {
147 #if	__BYTE_ORDER == __BIG_ENDIAN
148 	unsigned int negative:1;
149 	unsigned int exponent:15;
150 	unsigned int quiet_nan:1;
151 	/* Together these comprise the mantissa.  */
152 	unsigned int mantissa0:15;
153 	unsigned int mantissa1:32;
154 	unsigned int mantissa2:32;
155 	unsigned int mantissa3:32;
156 #else
157 	/* Together these comprise the mantissa.  */
158 	unsigned int mantissa3:32;
159 	unsigned int mantissa2:32;
160 	unsigned int mantissa1:32;
161 	unsigned int mantissa0:15;
162 	unsigned int quiet_nan:1;
163 	unsigned int exponent:15;
164 	unsigned int negative:1;
165 #endif
166       } ieee_nan;
167   };
168 
169 #define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent.  */
170 #endif
171 
172 
173 #if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 0 || __GNUC_PREREQ (7, 0)
174 /* IBM extended format for long double.
175 
176    Each long double is made up of two IEEE doubles.  The value of the
177    long double is the sum of the values of the two parts.  The most
178    significant part is required to be the value of the long double
179    rounded to the nearest double, as specified by IEEE.  For Inf
180    values, the least significant part is required to be one of +0.0 or
181    -0.0.  No other requirements are made; so, for example, 1.0 may be
182    represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
183    NaN is don't-care.  */
184 union ibm_extended_long_double
185   {
186 # if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1 && __GNUC_PREREQ (7, 0)
187    __ibm128 ld;
188 # else
189    long double ld;
190 # endif
191     union ieee754_double d[2];
192    };
193 #endif
194 
195 __END_DECLS
196 
197 #endif /* ieee754.h */
198