1 /*
2 Copyright (c) 1991, 1993
3 The Regents of the University of California.  All rights reserved.
4 c) UNIX System Laboratories, Inc.
5 All or some portions of this file are derived from material licensed
6 to the University of California by American Telephone and Telegraph
7 Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 the permission of UNIX System Laboratories, Inc.
9 
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions
12 are met:
13 1. Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15 2. Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18 3. Neither the name of the University nor the names of its contributors
19 may be used to endorse or promote products derived from this software
20 without specific prior written permission.
21 
22 THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 SUCH DAMAGE.
33  */
34 #ifndef _IEEE_FP_H_
35 #define _IEEE_FP_H_
36 
37 #include "_ansi.h"
38 
39 #include <machine/ieeefp.h>
40 #include <float.h>
41 #include <stdint.h>
42 
43 _BEGIN_STD_C
44 
45 #ifndef _LDBL_EQ_DBL
46 
47 #ifndef LDBL_MANT_DIG
48 #error "LDBL_MANT_DIG not defined - should be found in float.h"
49 
50 #elif LDBL_MANT_DIG == DBL_MANT_DIG
51 #error "double and long double are the same size but LDBL_EQ_DBL is not defined"
52 
53 #elif LDBL_MANT_DIG == 53
54 /* This happens when doubles are 32-bits and long doubles are 64-bits.  */
55 #define	EXT_EXPBITS	11
56 #define EXT_FRACHBITS	20
57 #define	EXT_FRACLBITS	32
58 #define __ieee_ext_field_type unsigned long
59 
60 #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 65) && LDBL_MAX_EXP == 16384
61 /* 80-bit floats, as on x86 */
62 #define	EXT_EXPBITS	15
63 #define EXT_FRACHBITS	32
64 #define	EXT_FRACLBITS	32
65 #ifdef __IEEE_BIG_ENDIAN
66 #define EXT_FRACGAP     16
67 #endif
68 #define __ieee_ext_field_type unsigned int
69 
70 #elif (LDBL_MANT_DIG == 113 || LDBL_MANT_DIG == 112) && LDBL_MAX_EXP == 16384
71 /* 128-bit IEEE floats, as on risc-v */
72 #define	EXT_EXPBITS	15
73 #define EXT_FRACHBITS	48
74 #define	EXT_FRACLBITS	64
75 #define __ieee_ext_field_type unsigned long long
76 
77 #elif LDBL_MANT_DIG == 106 && DBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
78 /* 128-bit double-double, as on powerpc */
79 #define EXT_EXPBITS     11
80 #define EXT_FRACHBITS   DBL_MANT_DIG
81 #define EXT_FRACLBITS   DBL_MANT_DIG
82 #define EXT_FRACGAP     EXT_EXPBITS
83 #define __ieee_ext_field_type unsigned long long
84 
85 #else
86 #error Unsupported value for LDBL_MANT_DIG
87 #endif
88 
89 #define	EXT_EXP_INFNAN	   ((1 << EXT_EXPBITS) - 1) /* 32767 */
90 #define	EXT_EXP_BIAS	   ((1 << (EXT_EXPBITS - 1)) - 1) /* 16383 */
91 #define	EXT_FRACBITS	   (EXT_FRACLBITS + EXT_FRACHBITS)
92 
93 typedef struct ieee_ext
94 {
95 #ifdef __IEEE_LITTLE_ENDIAN
96   __ieee_ext_field_type	 ext_fracl : EXT_FRACLBITS;
97 #ifdef EXT_FRACGAP
98   __ieee_ext_field_type  ext_gap   : EXT_FRACGAP;
99 #endif
100   __ieee_ext_field_type	 ext_frach : EXT_FRACHBITS;
101   __ieee_ext_field_type	 ext_exp   : EXT_EXPBITS;
102   __ieee_ext_field_type	 ext_sign  : 1;
103 #endif
104 #ifdef __IEEE_BIG_ENDIAN
105   __ieee_ext_field_type	 ext_sign  : 1;
106   __ieee_ext_field_type	 ext_exp   : EXT_EXPBITS;
107 #ifdef EXT_FRACGAP
108   __ieee_ext_field_type  ext_gap   : EXT_FRACGAP;
109 #endif
110   __ieee_ext_field_type	 ext_frach : EXT_FRACHBITS;
111   __ieee_ext_field_type	 ext_fracl : EXT_FRACLBITS;
112 #endif
113 } ieee_ext;
114 
115 typedef union ieee_ext_u
116 {
117   long double		extu_ld;
118   struct ieee_ext	extu_ext;
119 } ieee_ext_u;
120 
121 #endif /* ! _LDBL_EQ_DBL */
122 
123 
124 /* FLOATING ROUNDING */
125 
126 typedef int fp_rnd;
127 #define FP_RN 0 	/* Round to nearest 		*/
128 #define FP_RM 1		/* Round down 			*/
129 #define FP_RP 2		/* Round up 			*/
130 #define FP_RZ 3		/* Round to zero (trunate) 	*/
131 
132 fp_rnd fpgetround (void);
133 fp_rnd fpsetround (fp_rnd);
134 
135 /* EXCEPTIONS */
136 
137 typedef int fp_except;
138 #define FP_X_INV 0x10	/* Invalid operation 		*/
139 #define FP_X_DX  0x80	/* Divide by zero		*/
140 #define FP_X_OFL 0x04	/* Overflow exception		*/
141 #define FP_X_UFL 0x02	/* Underflow exception		*/
142 #define FP_X_IMP 0x01	/* imprecise exception		*/
143 
144 fp_except fpgetmask (void);
145 fp_except fpsetmask (fp_except);
146 fp_except fpgetsticky (void);
147 fp_except fpsetsticky (fp_except);
148 
149 /* INTEGER ROUNDING */
150 
151 typedef int fp_rdi;
152 #define FP_RDI_TOZ 0	/* Round to Zero 		*/
153 #define FP_RDI_RD  1	/* Follow float mode		*/
154 
155 fp_rdi fpgetroundtoi (void);
156 fp_rdi fpsetroundtoi (fp_rdi);
157 
158 #define __IEEE_DBL_EXPBIAS 1023
159 #define __IEEE_FLT_EXPBIAS 127
160 
161 #define __IEEE_DBL_EXPLEN 11
162 #define __IEEE_FLT_EXPLEN 8
163 
164 
165 #define __IEEE_DBL_FRACLEN (64 - (__IEEE_DBL_EXPLEN + 1))
166 #define __IEEE_FLT_FRACLEN (32 - (__IEEE_FLT_EXPLEN + 1))
167 
168 #define __IEEE_DBL_MAXPOWTWO	((double)(1L << 32 - 2) * (1L << (32-11) - 32 + 1))
169 #define __IEEE_FLT_MAXPOWTWO	((float)(1L << (32-8) - 1))
170 
171 #define __IEEE_DBL_NAN_EXP 0x7ff
172 #define __IEEE_FLT_NAN_EXP 0xff
173 
174 #ifdef __ieeefp_isnanf
175 #define isnanf(x)	__ieeefp_isnanf(x)
176 #endif
177 
178 #ifdef __ieeefp_isinff
179 #define isinff(x)	__ieeefp_isinff(x)
180 #endif
181 
182 #ifdef __ieeefp_finitef
183 #define finitef(x)	__ieeefp_finitef(x)
184 #endif
185 
186 #ifdef _DOUBLE_IS_32BITS
187 #undef __IEEE_DBL_EXPBIAS
188 #define __IEEE_DBL_EXPBIAS __IEEE_FLT_EXPBIAS
189 
190 #undef __IEEE_DBL_EXPLEN
191 #define __IEEE_DBL_EXPLEN __IEEE_FLT_EXPLEN
192 
193 #undef __IEEE_DBL_FRACLEN
194 #define __IEEE_DBL_FRACLEN __IEEE_FLT_FRACLEN
195 
196 #undef __IEEE_DBL_MAXPOWTWO
197 #define __IEEE_DBL_MAXPOWTWO __IEEE_FLT_MAXPOWTWO
198 
199 #undef __IEEE_DBL_NAN_EXP
200 #define __IEEE_DBL_NAN_EXP __IEEE_FLT_NAN_EXP
201 
202 #undef __ieee_double_shape_type
203 #define __ieee_double_shape_type __ieee_float_shape_type
204 
205 #endif /* _DOUBLE_IS_32BITS */
206 
207 _END_STD_C
208 
209 #endif /* _IEEE_FP_H_ */
210