xref: /minix3/lib/libc/arch/aarch64/softfloat/softfloat.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /* $NetBSD: softfloat.h,v 1.1 2014/08/10 05:47:37 matt Exp $ */
2*0a6a1f1dSLionel Sambuc 
3*0a6a1f1dSLionel Sambuc /* This is a derivative work. */
4*0a6a1f1dSLionel Sambuc 
5*0a6a1f1dSLionel Sambuc /*
6*0a6a1f1dSLionel Sambuc ===============================================================================
7*0a6a1f1dSLionel Sambuc 
8*0a6a1f1dSLionel Sambuc This C header file is part of the SoftFloat IEC/IEEE Floating-point
9*0a6a1f1dSLionel Sambuc Arithmetic Package, Release 2a.
10*0a6a1f1dSLionel Sambuc 
11*0a6a1f1dSLionel Sambuc Written by John R. Hauser.  This work was made possible in part by the
12*0a6a1f1dSLionel Sambuc International Computer Science Institute, located at Suite 600, 1947 Center
13*0a6a1f1dSLionel Sambuc Street, Berkeley, California 94704.  Funding was partially provided by the
14*0a6a1f1dSLionel Sambuc National Science Foundation under grant MIP-9311980.  The original version
15*0a6a1f1dSLionel Sambuc of this code was written as part of a project to build a fixed-point vector
16*0a6a1f1dSLionel Sambuc processor in collaboration with the University of California at Berkeley,
17*0a6a1f1dSLionel Sambuc overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
18*0a6a1f1dSLionel Sambuc is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
19*0a6a1f1dSLionel Sambuc arithmetic/SoftFloat.html'.
20*0a6a1f1dSLionel Sambuc 
21*0a6a1f1dSLionel Sambuc THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
22*0a6a1f1dSLionel Sambuc has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
23*0a6a1f1dSLionel Sambuc TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
24*0a6a1f1dSLionel Sambuc PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
25*0a6a1f1dSLionel Sambuc AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
26*0a6a1f1dSLionel Sambuc 
27*0a6a1f1dSLionel Sambuc Derivative works are acceptable, even for commercial purposes, so long as
28*0a6a1f1dSLionel Sambuc (1) they include prominent notice that the work is derivative, and (2) they
29*0a6a1f1dSLionel Sambuc include prominent notice akin to these four paragraphs for those parts of
30*0a6a1f1dSLionel Sambuc this code that are retained.
31*0a6a1f1dSLionel Sambuc 
32*0a6a1f1dSLionel Sambuc ===============================================================================
33*0a6a1f1dSLionel Sambuc */
34*0a6a1f1dSLionel Sambuc 
35*0a6a1f1dSLionel Sambuc /*
36*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
37*0a6a1f1dSLionel Sambuc The macro `FLOATX80' must be defined to enable the extended double-precision
38*0a6a1f1dSLionel Sambuc floating-point format `floatx80'.  If this macro is not defined, the
39*0a6a1f1dSLionel Sambuc `floatx80' type will not be defined, and none of the functions that either
40*0a6a1f1dSLionel Sambuc input or output the `floatx80' type will be defined.  The same applies to
41*0a6a1f1dSLionel Sambuc the `FLOAT128' macro and the quadruple-precision format `float128'.
42*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
43*0a6a1f1dSLionel Sambuc */
44*0a6a1f1dSLionel Sambuc /* #define FLOATX80 */
45*0a6a1f1dSLionel Sambuc #define FLOAT128
46*0a6a1f1dSLionel Sambuc 
47*0a6a1f1dSLionel Sambuc #include "softfloat-qp.h"
48*0a6a1f1dSLionel Sambuc 
49*0a6a1f1dSLionel Sambuc #include <machine/ieeefp.h>
50*0a6a1f1dSLionel Sambuc 
51*0a6a1f1dSLionel Sambuc /*
52*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
53*0a6a1f1dSLionel Sambuc Software IEC/IEEE floating-point types.
54*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
55*0a6a1f1dSLionel Sambuc */
56*0a6a1f1dSLionel Sambuc typedef unsigned int float32;
57*0a6a1f1dSLionel Sambuc typedef unsigned long long float64;
58*0a6a1f1dSLionel Sambuc #ifdef FLOATX80
59*0a6a1f1dSLionel Sambuc typedef struct {
60*0a6a1f1dSLionel Sambuc     unsigned short high;
61*0a6a1f1dSLionel Sambuc     unsigned long long low;
62*0a6a1f1dSLionel Sambuc } floatx80;
63*0a6a1f1dSLionel Sambuc #endif
64*0a6a1f1dSLionel Sambuc #ifdef FLOAT128
65*0a6a1f1dSLionel Sambuc typedef struct {
66*0a6a1f1dSLionel Sambuc     unsigned long long high, low;
67*0a6a1f1dSLionel Sambuc } float128;
68*0a6a1f1dSLionel Sambuc #endif
69*0a6a1f1dSLionel Sambuc 
70*0a6a1f1dSLionel Sambuc /*
71*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
72*0a6a1f1dSLionel Sambuc Software IEC/IEEE floating-point underflow tininess-detection mode.
73*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
74*0a6a1f1dSLionel Sambuc */
75*0a6a1f1dSLionel Sambuc #ifndef SOFTFLOAT_FOR_GCC
76*0a6a1f1dSLionel Sambuc extern int8 float_detect_tininess;
77*0a6a1f1dSLionel Sambuc #endif
78*0a6a1f1dSLionel Sambuc enum {
79*0a6a1f1dSLionel Sambuc     float_tininess_after_rounding  = 0,
80*0a6a1f1dSLionel Sambuc     float_tininess_before_rounding = 1
81*0a6a1f1dSLionel Sambuc };
82*0a6a1f1dSLionel Sambuc 
83*0a6a1f1dSLionel Sambuc /*
84*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
85*0a6a1f1dSLionel Sambuc Software IEC/IEEE floating-point rounding mode.
86*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
87*0a6a1f1dSLionel Sambuc */
88*0a6a1f1dSLionel Sambuc extern fp_rnd float_rounding_mode;
89*0a6a1f1dSLionel Sambuc #define float_round_nearest_even FP_RN
90*0a6a1f1dSLionel Sambuc #define float_round_to_zero      FP_RZ
91*0a6a1f1dSLionel Sambuc #define float_round_down         FP_RM
92*0a6a1f1dSLionel Sambuc #define float_round_up           FP_RP
93*0a6a1f1dSLionel Sambuc 
94*0a6a1f1dSLionel Sambuc /*
95*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
96*0a6a1f1dSLionel Sambuc Software IEC/IEEE floating-point exception flags.
97*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
98*0a6a1f1dSLionel Sambuc */
99*0a6a1f1dSLionel Sambuc extern fp_except float_exception_flags;
100*0a6a1f1dSLionel Sambuc extern fp_except float_exception_mask;
101*0a6a1f1dSLionel Sambuc enum {
102*0a6a1f1dSLionel Sambuc     float_flag_inexact   = FP_X_IMP,
103*0a6a1f1dSLionel Sambuc     float_flag_underflow = FP_X_UFL,
104*0a6a1f1dSLionel Sambuc     float_flag_overflow  = FP_X_OFL,
105*0a6a1f1dSLionel Sambuc     float_flag_divbyzero = FP_X_DZ,
106*0a6a1f1dSLionel Sambuc     float_flag_invalid   = FP_X_INV
107*0a6a1f1dSLionel Sambuc };
108*0a6a1f1dSLionel Sambuc 
109*0a6a1f1dSLionel Sambuc /*
110*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
111*0a6a1f1dSLionel Sambuc Routine to raise any or all of the software IEC/IEEE floating-point
112*0a6a1f1dSLionel Sambuc exception flags.
113*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
114*0a6a1f1dSLionel Sambuc */
115*0a6a1f1dSLionel Sambuc void float_raise( fp_except );
116*0a6a1f1dSLionel Sambuc 
117*0a6a1f1dSLionel Sambuc /*
118*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
119*0a6a1f1dSLionel Sambuc Software IEC/IEEE integer-to-floating-point conversion routines.
120*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
121*0a6a1f1dSLionel Sambuc */
122*0a6a1f1dSLionel Sambuc float32 int32_to_float32( int32 );
123*0a6a1f1dSLionel Sambuc float32 uint32_to_float32( uint32 );
124*0a6a1f1dSLionel Sambuc float64 int32_to_float64( int32 );
125*0a6a1f1dSLionel Sambuc float64 uint32_to_float64( uint32 );
126*0a6a1f1dSLionel Sambuc #ifdef FLOATX80
127*0a6a1f1dSLionel Sambuc floatx80 int32_to_floatx80( int32 );
128*0a6a1f1dSLionel Sambuc floatx80 uint32_to_floatx80( uint32 );
129*0a6a1f1dSLionel Sambuc #endif
130*0a6a1f1dSLionel Sambuc #ifdef FLOAT128
131*0a6a1f1dSLionel Sambuc float128 int32_to_float128( int32 );
132*0a6a1f1dSLionel Sambuc float128 uint32_to_float128( uint32 );
133*0a6a1f1dSLionel Sambuc #endif
134*0a6a1f1dSLionel Sambuc float32 int64_to_float32( long long );
135*0a6a1f1dSLionel Sambuc float64 int64_to_float64( long long );
136*0a6a1f1dSLionel Sambuc #ifdef FLOATX80
137*0a6a1f1dSLionel Sambuc floatx80 int64_to_floatx80( long long );
138*0a6a1f1dSLionel Sambuc #endif
139*0a6a1f1dSLionel Sambuc #ifdef FLOAT128
140*0a6a1f1dSLionel Sambuc float128 int64_to_float128( long long );
141*0a6a1f1dSLionel Sambuc #endif
142*0a6a1f1dSLionel Sambuc 
143*0a6a1f1dSLionel Sambuc /*
144*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
145*0a6a1f1dSLionel Sambuc Software IEC/IEEE single-precision conversion routines.
146*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
147*0a6a1f1dSLionel Sambuc */
148*0a6a1f1dSLionel Sambuc int float32_to_int32( float32 );
149*0a6a1f1dSLionel Sambuc int float32_to_int32_round_to_zero( float32 );
150*0a6a1f1dSLionel Sambuc unsigned int float32_to_uint32_round_to_zero( float32 );
151*0a6a1f1dSLionel Sambuc long long float32_to_int64( float32 );
152*0a6a1f1dSLionel Sambuc long long float32_to_int64_round_to_zero( float32 );
153*0a6a1f1dSLionel Sambuc float64 float32_to_float64( float32 );
154*0a6a1f1dSLionel Sambuc #ifdef FLOATX80
155*0a6a1f1dSLionel Sambuc floatx80 float32_to_floatx80( float32 );
156*0a6a1f1dSLionel Sambuc #endif
157*0a6a1f1dSLionel Sambuc #ifdef FLOAT128
158*0a6a1f1dSLionel Sambuc float128 float32_to_float128( float32 );
159*0a6a1f1dSLionel Sambuc #endif
160*0a6a1f1dSLionel Sambuc 
161*0a6a1f1dSLionel Sambuc /*
162*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
163*0a6a1f1dSLionel Sambuc Software IEC/IEEE single-precision operations.
164*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
165*0a6a1f1dSLionel Sambuc */
166*0a6a1f1dSLionel Sambuc float32 float32_round_to_int( float32 );
167*0a6a1f1dSLionel Sambuc float32 float32_add( float32, float32 );
168*0a6a1f1dSLionel Sambuc float32 float32_sub( float32, float32 );
169*0a6a1f1dSLionel Sambuc float32 float32_mul( float32, float32 );
170*0a6a1f1dSLionel Sambuc float32 float32_div( float32, float32 );
171*0a6a1f1dSLionel Sambuc float32 float32_rem( float32, float32 );
172*0a6a1f1dSLionel Sambuc float32 float32_sqrt( float32 );
173*0a6a1f1dSLionel Sambuc flag float32_eq( float32, float32 );
174*0a6a1f1dSLionel Sambuc flag float32_le( float32, float32 );
175*0a6a1f1dSLionel Sambuc flag float32_lt( float32, float32 );
176*0a6a1f1dSLionel Sambuc flag float32_eq_signaling( float32, float32 );
177*0a6a1f1dSLionel Sambuc flag float32_le_quiet( float32, float32 );
178*0a6a1f1dSLionel Sambuc flag float32_lt_quiet( float32, float32 );
179*0a6a1f1dSLionel Sambuc flag float32_is_signaling_nan( float32 );
180*0a6a1f1dSLionel Sambuc 
181*0a6a1f1dSLionel Sambuc /*
182*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
183*0a6a1f1dSLionel Sambuc Software IEC/IEEE double-precision conversion routines.
184*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
185*0a6a1f1dSLionel Sambuc */
186*0a6a1f1dSLionel Sambuc int float64_to_int32( float64 );
187*0a6a1f1dSLionel Sambuc int float64_to_int32_round_to_zero( float64 );
188*0a6a1f1dSLionel Sambuc unsigned int float64_to_uint32_round_to_zero( float64 );
189*0a6a1f1dSLionel Sambuc long long float64_to_int64( float64 );
190*0a6a1f1dSLionel Sambuc long long float64_to_int64_round_to_zero( float64 );
191*0a6a1f1dSLionel Sambuc float32 float64_to_float32( float64 );
192*0a6a1f1dSLionel Sambuc #ifdef FLOATX80
193*0a6a1f1dSLionel Sambuc floatx80 float64_to_floatx80( float64 );
194*0a6a1f1dSLionel Sambuc #endif
195*0a6a1f1dSLionel Sambuc #ifdef FLOAT128
196*0a6a1f1dSLionel Sambuc float128 float64_to_float128( float64 );
197*0a6a1f1dSLionel Sambuc #endif
198*0a6a1f1dSLionel Sambuc 
199*0a6a1f1dSLionel Sambuc /*
200*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
201*0a6a1f1dSLionel Sambuc Software IEC/IEEE double-precision operations.
202*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
203*0a6a1f1dSLionel Sambuc */
204*0a6a1f1dSLionel Sambuc float64 float64_round_to_int( float64 );
205*0a6a1f1dSLionel Sambuc float64 float64_add( float64, float64 );
206*0a6a1f1dSLionel Sambuc float64 float64_sub( float64, float64 );
207*0a6a1f1dSLionel Sambuc float64 float64_mul( float64, float64 );
208*0a6a1f1dSLionel Sambuc float64 float64_div( float64, float64 );
209*0a6a1f1dSLionel Sambuc float64 float64_rem( float64, float64 );
210*0a6a1f1dSLionel Sambuc float64 float64_sqrt( float64 );
211*0a6a1f1dSLionel Sambuc flag float64_eq( float64, float64 );
212*0a6a1f1dSLionel Sambuc flag float64_le( float64, float64 );
213*0a6a1f1dSLionel Sambuc flag float64_lt( float64, float64 );
214*0a6a1f1dSLionel Sambuc flag float64_eq_signaling( float64, float64 );
215*0a6a1f1dSLionel Sambuc flag float64_le_quiet( float64, float64 );
216*0a6a1f1dSLionel Sambuc flag float64_lt_quiet( float64, float64 );
217*0a6a1f1dSLionel Sambuc flag float64_is_signaling_nan( float64 );
218*0a6a1f1dSLionel Sambuc 
219*0a6a1f1dSLionel Sambuc #ifdef FLOATX80
220*0a6a1f1dSLionel Sambuc 
221*0a6a1f1dSLionel Sambuc /*
222*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
223*0a6a1f1dSLionel Sambuc Software IEC/IEEE extended double-precision conversion routines.
224*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
225*0a6a1f1dSLionel Sambuc */
226*0a6a1f1dSLionel Sambuc int floatx80_to_int32( floatx80 );
227*0a6a1f1dSLionel Sambuc int floatx80_to_int32_round_to_zero( floatx80 );
228*0a6a1f1dSLionel Sambuc long long floatx80_to_int64( floatx80 );
229*0a6a1f1dSLionel Sambuc long long floatx80_to_int64_round_to_zero( floatx80 );
230*0a6a1f1dSLionel Sambuc float32 floatx80_to_float32( floatx80 );
231*0a6a1f1dSLionel Sambuc float64 floatx80_to_float64( floatx80 );
232*0a6a1f1dSLionel Sambuc #ifdef FLOAT128
233*0a6a1f1dSLionel Sambuc float128 floatx80_to_float128( floatx80 );
234*0a6a1f1dSLionel Sambuc #endif
235*0a6a1f1dSLionel Sambuc 
236*0a6a1f1dSLionel Sambuc /*
237*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
238*0a6a1f1dSLionel Sambuc Software IEC/IEEE extended double-precision rounding precision.  Valid
239*0a6a1f1dSLionel Sambuc values are 32, 64, and 80.
240*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
241*0a6a1f1dSLionel Sambuc */
242*0a6a1f1dSLionel Sambuc extern int floatx80_rounding_precision;
243*0a6a1f1dSLionel Sambuc 
244*0a6a1f1dSLionel Sambuc /*
245*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
246*0a6a1f1dSLionel Sambuc Software IEC/IEEE extended double-precision operations.
247*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
248*0a6a1f1dSLionel Sambuc */
249*0a6a1f1dSLionel Sambuc floatx80 floatx80_round_to_int( floatx80 );
250*0a6a1f1dSLionel Sambuc floatx80 floatx80_add( floatx80, floatx80 );
251*0a6a1f1dSLionel Sambuc floatx80 floatx80_sub( floatx80, floatx80 );
252*0a6a1f1dSLionel Sambuc floatx80 floatx80_mul( floatx80, floatx80 );
253*0a6a1f1dSLionel Sambuc floatx80 floatx80_div( floatx80, floatx80 );
254*0a6a1f1dSLionel Sambuc floatx80 floatx80_rem( floatx80, floatx80 );
255*0a6a1f1dSLionel Sambuc floatx80 floatx80_sqrt( floatx80 );
256*0a6a1f1dSLionel Sambuc flag floatx80_eq( floatx80, floatx80 );
257*0a6a1f1dSLionel Sambuc flag floatx80_le( floatx80, floatx80 );
258*0a6a1f1dSLionel Sambuc flag floatx80_lt( floatx80, floatx80 );
259*0a6a1f1dSLionel Sambuc flag floatx80_eq_signaling( floatx80, floatx80 );
260*0a6a1f1dSLionel Sambuc flag floatx80_le_quiet( floatx80, floatx80 );
261*0a6a1f1dSLionel Sambuc flag floatx80_lt_quiet( floatx80, floatx80 );
262*0a6a1f1dSLionel Sambuc flag floatx80_is_signaling_nan( floatx80 );
263*0a6a1f1dSLionel Sambuc 
264*0a6a1f1dSLionel Sambuc #endif
265*0a6a1f1dSLionel Sambuc 
266*0a6a1f1dSLionel Sambuc #ifdef FLOAT128
267*0a6a1f1dSLionel Sambuc 
268*0a6a1f1dSLionel Sambuc /*
269*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
270*0a6a1f1dSLionel Sambuc Software IEC/IEEE quadruple-precision conversion routines.
271*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
272*0a6a1f1dSLionel Sambuc */
273*0a6a1f1dSLionel Sambuc int float128_to_int32( float128 );
274*0a6a1f1dSLionel Sambuc int float128_to_int32_round_to_zero( float128 );
275*0a6a1f1dSLionel Sambuc long long float128_to_int64( float128 );
276*0a6a1f1dSLionel Sambuc long long float128_to_int64_round_to_zero( float128 );
277*0a6a1f1dSLionel Sambuc unsigned long long float128_to_uint64_round_to_zero( float128 );
278*0a6a1f1dSLionel Sambuc float32 float128_to_float32( float128 );
279*0a6a1f1dSLionel Sambuc float64 float128_to_float64( float128 );
280*0a6a1f1dSLionel Sambuc #ifdef FLOATX80
281*0a6a1f1dSLionel Sambuc floatx80 float128_to_floatx80( float128 );
282*0a6a1f1dSLionel Sambuc #endif
283*0a6a1f1dSLionel Sambuc 
284*0a6a1f1dSLionel Sambuc /*
285*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
286*0a6a1f1dSLionel Sambuc Software IEC/IEEE quadruple-precision operations.
287*0a6a1f1dSLionel Sambuc -------------------------------------------------------------------------------
288*0a6a1f1dSLionel Sambuc */
289*0a6a1f1dSLionel Sambuc float128 float128_round_to_int( float128 );
290*0a6a1f1dSLionel Sambuc float128 float128_add( float128, float128 );
291*0a6a1f1dSLionel Sambuc float128 float128_sub( float128, float128 );
292*0a6a1f1dSLionel Sambuc float128 float128_mul( float128, float128 );
293*0a6a1f1dSLionel Sambuc float128 float128_div( float128, float128 );
294*0a6a1f1dSLionel Sambuc float128 float128_rem( float128, float128 );
295*0a6a1f1dSLionel Sambuc float128 float128_sqrt( float128 );
296*0a6a1f1dSLionel Sambuc flag float128_eq( float128, float128 );
297*0a6a1f1dSLionel Sambuc flag float128_le( float128, float128 );
298*0a6a1f1dSLionel Sambuc flag float128_lt( float128, float128 );
299*0a6a1f1dSLionel Sambuc flag float128_eq_signaling( float128, float128 );
300*0a6a1f1dSLionel Sambuc flag float128_le_quiet( float128, float128 );
301*0a6a1f1dSLionel Sambuc flag float128_lt_quiet( float128, float128 );
302*0a6a1f1dSLionel Sambuc flag float128_is_signaling_nan( float128 );
303*0a6a1f1dSLionel Sambuc flag float128_is_nan( float128 );
304*0a6a1f1dSLionel Sambuc 
305*0a6a1f1dSLionel Sambuc #endif
306