xref: /openbmc/linux/arch/arm/nwfpe/softfloat.h (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus Torvalds 
2*1da177e4SLinus Torvalds /*
3*1da177e4SLinus Torvalds ===============================================================================
4*1da177e4SLinus Torvalds 
5*1da177e4SLinus Torvalds This C header file is part of the SoftFloat IEC/IEEE Floating-point
6*1da177e4SLinus Torvalds Arithmetic Package, Release 2.
7*1da177e4SLinus Torvalds 
8*1da177e4SLinus Torvalds Written by John R. Hauser.  This work was made possible in part by the
9*1da177e4SLinus Torvalds International Computer Science Institute, located at Suite 600, 1947 Center
10*1da177e4SLinus Torvalds Street, Berkeley, California 94704.  Funding was partially provided by the
11*1da177e4SLinus Torvalds National Science Foundation under grant MIP-9311980.  The original version
12*1da177e4SLinus Torvalds of this code was written as part of a project to build a fixed-point vector
13*1da177e4SLinus Torvalds processor in collaboration with the University of California at Berkeley,
14*1da177e4SLinus Torvalds overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
15*1da177e4SLinus Torvalds is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
16*1da177e4SLinus Torvalds arithmetic/softfloat.html'.
17*1da177e4SLinus Torvalds 
18*1da177e4SLinus Torvalds THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
19*1da177e4SLinus Torvalds has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
20*1da177e4SLinus Torvalds TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
21*1da177e4SLinus Torvalds PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
22*1da177e4SLinus Torvalds AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
23*1da177e4SLinus Torvalds 
24*1da177e4SLinus Torvalds Derivative works are acceptable, even for commercial purposes, so long as
25*1da177e4SLinus Torvalds (1) they include prominent notice that the work is derivative, and (2) they
26*1da177e4SLinus Torvalds include prominent notice akin to these three paragraphs for those parts of
27*1da177e4SLinus Torvalds this code that are retained.
28*1da177e4SLinus Torvalds 
29*1da177e4SLinus Torvalds ===============================================================================
30*1da177e4SLinus Torvalds */
31*1da177e4SLinus Torvalds 
32*1da177e4SLinus Torvalds #ifndef __SOFTFLOAT_H__
33*1da177e4SLinus Torvalds #define __SOFTFLOAT_H__
34*1da177e4SLinus Torvalds 
35*1da177e4SLinus Torvalds #include <linux/config.h>
36*1da177e4SLinus Torvalds 
37*1da177e4SLinus Torvalds /*
38*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
39*1da177e4SLinus Torvalds The macro `FLOATX80' must be defined to enable the extended double-precision
40*1da177e4SLinus Torvalds floating-point format `floatx80'.  If this macro is not defined, the
41*1da177e4SLinus Torvalds `floatx80' type will not be defined, and none of the functions that either
42*1da177e4SLinus Torvalds input or output the `floatx80' type will be defined.
43*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
44*1da177e4SLinus Torvalds */
45*1da177e4SLinus Torvalds #ifdef CONFIG_FPE_NWFPE_XP
46*1da177e4SLinus Torvalds #define FLOATX80
47*1da177e4SLinus Torvalds #endif
48*1da177e4SLinus Torvalds 
49*1da177e4SLinus Torvalds /*
50*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
51*1da177e4SLinus Torvalds Software IEC/IEEE floating-point types.
52*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
53*1da177e4SLinus Torvalds */
54*1da177e4SLinus Torvalds typedef unsigned long int float32;
55*1da177e4SLinus Torvalds typedef unsigned long long float64;
56*1da177e4SLinus Torvalds typedef struct {
57*1da177e4SLinus Torvalds     unsigned short high;
58*1da177e4SLinus Torvalds     unsigned long long low;
59*1da177e4SLinus Torvalds } floatx80;
60*1da177e4SLinus Torvalds 
61*1da177e4SLinus Torvalds /*
62*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
63*1da177e4SLinus Torvalds Software IEC/IEEE floating-point underflow tininess-detection mode.
64*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
65*1da177e4SLinus Torvalds */
66*1da177e4SLinus Torvalds extern signed char float_detect_tininess;
67*1da177e4SLinus Torvalds enum {
68*1da177e4SLinus Torvalds     float_tininess_after_rounding  = 0,
69*1da177e4SLinus Torvalds     float_tininess_before_rounding = 1
70*1da177e4SLinus Torvalds };
71*1da177e4SLinus Torvalds 
72*1da177e4SLinus Torvalds /*
73*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
74*1da177e4SLinus Torvalds Software IEC/IEEE floating-point rounding mode.
75*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
76*1da177e4SLinus Torvalds */
77*1da177e4SLinus Torvalds extern signed char float_rounding_mode;
78*1da177e4SLinus Torvalds enum {
79*1da177e4SLinus Torvalds     float_round_nearest_even = 0,
80*1da177e4SLinus Torvalds     float_round_to_zero      = 1,
81*1da177e4SLinus Torvalds     float_round_down         = 2,
82*1da177e4SLinus Torvalds     float_round_up           = 3
83*1da177e4SLinus Torvalds };
84*1da177e4SLinus Torvalds 
85*1da177e4SLinus Torvalds /*
86*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
87*1da177e4SLinus Torvalds Software IEC/IEEE floating-point exception flags.
88*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
89*1da177e4SLinus Torvalds extern signed char float_exception_flags;
90*1da177e4SLinus Torvalds enum {
91*1da177e4SLinus Torvalds     float_flag_inexact   =  1,
92*1da177e4SLinus Torvalds     float_flag_underflow =  2,
93*1da177e4SLinus Torvalds     float_flag_overflow  =  4,
94*1da177e4SLinus Torvalds     float_flag_divbyzero =  8,
95*1da177e4SLinus Torvalds     float_flag_invalid   = 16
96*1da177e4SLinus Torvalds };
97*1da177e4SLinus Torvalds 
98*1da177e4SLinus Torvalds ScottB: November 4, 1998
99*1da177e4SLinus Torvalds Changed the enumeration to match the bit order in the FPA11.
100*1da177e4SLinus Torvalds */
101*1da177e4SLinus Torvalds 
102*1da177e4SLinus Torvalds extern signed char float_exception_flags;
103*1da177e4SLinus Torvalds enum {
104*1da177e4SLinus Torvalds     float_flag_invalid   =  1,
105*1da177e4SLinus Torvalds     float_flag_divbyzero =  2,
106*1da177e4SLinus Torvalds     float_flag_overflow  =  4,
107*1da177e4SLinus Torvalds     float_flag_underflow =  8,
108*1da177e4SLinus Torvalds     float_flag_inexact   = 16
109*1da177e4SLinus Torvalds };
110*1da177e4SLinus Torvalds 
111*1da177e4SLinus Torvalds /*
112*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
113*1da177e4SLinus Torvalds Routine to raise any or all of the software IEC/IEEE floating-point
114*1da177e4SLinus Torvalds exception flags.
115*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
116*1da177e4SLinus Torvalds */
117*1da177e4SLinus Torvalds void float_raise( signed char );
118*1da177e4SLinus Torvalds 
119*1da177e4SLinus Torvalds /*
120*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
121*1da177e4SLinus Torvalds Software IEC/IEEE integer-to-floating-point conversion routines.
122*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
123*1da177e4SLinus Torvalds */
124*1da177e4SLinus Torvalds float32 int32_to_float32( signed int );
125*1da177e4SLinus Torvalds float64 int32_to_float64( signed int );
126*1da177e4SLinus Torvalds #ifdef FLOATX80
127*1da177e4SLinus Torvalds floatx80 int32_to_floatx80( signed int );
128*1da177e4SLinus Torvalds #endif
129*1da177e4SLinus Torvalds 
130*1da177e4SLinus Torvalds /*
131*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
132*1da177e4SLinus Torvalds Software IEC/IEEE single-precision conversion routines.
133*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
134*1da177e4SLinus Torvalds */
135*1da177e4SLinus Torvalds signed int float32_to_int32( float32 );
136*1da177e4SLinus Torvalds signed int float32_to_int32_round_to_zero( float32 );
137*1da177e4SLinus Torvalds float64 float32_to_float64( float32 );
138*1da177e4SLinus Torvalds #ifdef FLOATX80
139*1da177e4SLinus Torvalds floatx80 float32_to_floatx80( float32 );
140*1da177e4SLinus Torvalds #endif
141*1da177e4SLinus Torvalds 
142*1da177e4SLinus Torvalds /*
143*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
144*1da177e4SLinus Torvalds Software IEC/IEEE single-precision operations.
145*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
146*1da177e4SLinus Torvalds */
147*1da177e4SLinus Torvalds float32 float32_round_to_int( float32 );
148*1da177e4SLinus Torvalds float32 float32_add( float32, float32 );
149*1da177e4SLinus Torvalds float32 float32_sub( float32, float32 );
150*1da177e4SLinus Torvalds float32 float32_mul( float32, float32 );
151*1da177e4SLinus Torvalds float32 float32_div( float32, float32 );
152*1da177e4SLinus Torvalds float32 float32_rem( float32, float32 );
153*1da177e4SLinus Torvalds float32 float32_sqrt( float32 );
154*1da177e4SLinus Torvalds char float32_eq( float32, float32 );
155*1da177e4SLinus Torvalds char float32_le( float32, float32 );
156*1da177e4SLinus Torvalds char float32_lt( float32, float32 );
157*1da177e4SLinus Torvalds char float32_eq_signaling( float32, float32 );
158*1da177e4SLinus Torvalds char float32_le_quiet( float32, float32 );
159*1da177e4SLinus Torvalds char float32_lt_quiet( float32, float32 );
160*1da177e4SLinus Torvalds char float32_is_signaling_nan( float32 );
161*1da177e4SLinus Torvalds 
162*1da177e4SLinus Torvalds /*
163*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
164*1da177e4SLinus Torvalds Software IEC/IEEE double-precision conversion routines.
165*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
166*1da177e4SLinus Torvalds */
167*1da177e4SLinus Torvalds signed int float64_to_int32( float64 );
168*1da177e4SLinus Torvalds signed int float64_to_int32_round_to_zero( float64 );
169*1da177e4SLinus Torvalds float32 float64_to_float32( float64 );
170*1da177e4SLinus Torvalds #ifdef FLOATX80
171*1da177e4SLinus Torvalds floatx80 float64_to_floatx80( float64 );
172*1da177e4SLinus Torvalds #endif
173*1da177e4SLinus Torvalds 
174*1da177e4SLinus Torvalds /*
175*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
176*1da177e4SLinus Torvalds Software IEC/IEEE double-precision operations.
177*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
178*1da177e4SLinus Torvalds */
179*1da177e4SLinus Torvalds float64 float64_round_to_int( float64 );
180*1da177e4SLinus Torvalds float64 float64_add( float64, float64 );
181*1da177e4SLinus Torvalds float64 float64_sub( float64, float64 );
182*1da177e4SLinus Torvalds float64 float64_mul( float64, float64 );
183*1da177e4SLinus Torvalds float64 float64_div( float64, float64 );
184*1da177e4SLinus Torvalds float64 float64_rem( float64, float64 );
185*1da177e4SLinus Torvalds float64 float64_sqrt( float64 );
186*1da177e4SLinus Torvalds char float64_eq( float64, float64 );
187*1da177e4SLinus Torvalds char float64_le( float64, float64 );
188*1da177e4SLinus Torvalds char float64_lt( float64, float64 );
189*1da177e4SLinus Torvalds char float64_eq_signaling( float64, float64 );
190*1da177e4SLinus Torvalds char float64_le_quiet( float64, float64 );
191*1da177e4SLinus Torvalds char float64_lt_quiet( float64, float64 );
192*1da177e4SLinus Torvalds char float64_is_signaling_nan( float64 );
193*1da177e4SLinus Torvalds 
194*1da177e4SLinus Torvalds #ifdef FLOATX80
195*1da177e4SLinus Torvalds 
196*1da177e4SLinus Torvalds /*
197*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
198*1da177e4SLinus Torvalds Software IEC/IEEE extended double-precision conversion routines.
199*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
200*1da177e4SLinus Torvalds */
201*1da177e4SLinus Torvalds signed int floatx80_to_int32( floatx80 );
202*1da177e4SLinus Torvalds signed int floatx80_to_int32_round_to_zero( floatx80 );
203*1da177e4SLinus Torvalds float32 floatx80_to_float32( floatx80 );
204*1da177e4SLinus Torvalds float64 floatx80_to_float64( floatx80 );
205*1da177e4SLinus Torvalds 
206*1da177e4SLinus Torvalds /*
207*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
208*1da177e4SLinus Torvalds Software IEC/IEEE extended double-precision rounding precision.  Valid
209*1da177e4SLinus Torvalds values are 32, 64, and 80.
210*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
211*1da177e4SLinus Torvalds */
212*1da177e4SLinus Torvalds extern signed char floatx80_rounding_precision;
213*1da177e4SLinus Torvalds 
214*1da177e4SLinus Torvalds /*
215*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
216*1da177e4SLinus Torvalds Software IEC/IEEE extended double-precision operations.
217*1da177e4SLinus Torvalds -------------------------------------------------------------------------------
218*1da177e4SLinus Torvalds */
219*1da177e4SLinus Torvalds floatx80 floatx80_round_to_int( floatx80 );
220*1da177e4SLinus Torvalds floatx80 floatx80_add( floatx80, floatx80 );
221*1da177e4SLinus Torvalds floatx80 floatx80_sub( floatx80, floatx80 );
222*1da177e4SLinus Torvalds floatx80 floatx80_mul( floatx80, floatx80 );
223*1da177e4SLinus Torvalds floatx80 floatx80_div( floatx80, floatx80 );
224*1da177e4SLinus Torvalds floatx80 floatx80_rem( floatx80, floatx80 );
225*1da177e4SLinus Torvalds floatx80 floatx80_sqrt( floatx80 );
226*1da177e4SLinus Torvalds char floatx80_eq( floatx80, floatx80 );
227*1da177e4SLinus Torvalds char floatx80_le( floatx80, floatx80 );
228*1da177e4SLinus Torvalds char floatx80_lt( floatx80, floatx80 );
229*1da177e4SLinus Torvalds char floatx80_eq_signaling( floatx80, floatx80 );
230*1da177e4SLinus Torvalds char floatx80_le_quiet( floatx80, floatx80 );
231*1da177e4SLinus Torvalds char floatx80_lt_quiet( floatx80, floatx80 );
232*1da177e4SLinus Torvalds char floatx80_is_signaling_nan( floatx80 );
233*1da177e4SLinus Torvalds 
234*1da177e4SLinus Torvalds #endif
235*1da177e4SLinus Torvalds 
236*1da177e4SLinus Torvalds static inline flag extractFloat32Sign(float32 a)
237*1da177e4SLinus Torvalds {
238*1da177e4SLinus Torvalds 	return a >> 31;
239*1da177e4SLinus Torvalds }
240*1da177e4SLinus Torvalds 
241*1da177e4SLinus Torvalds static inline flag float32_eq_nocheck(float32 a, float32 b)
242*1da177e4SLinus Torvalds {
243*1da177e4SLinus Torvalds 	return (a == b) || ((bits32) ((a | b) << 1) == 0);
244*1da177e4SLinus Torvalds }
245*1da177e4SLinus Torvalds 
246*1da177e4SLinus Torvalds static inline flag float32_lt_nocheck(float32 a, float32 b)
247*1da177e4SLinus Torvalds {
248*1da177e4SLinus Torvalds 	flag aSign, bSign;
249*1da177e4SLinus Torvalds 
250*1da177e4SLinus Torvalds 	aSign = extractFloat32Sign(a);
251*1da177e4SLinus Torvalds 	bSign = extractFloat32Sign(b);
252*1da177e4SLinus Torvalds 	if (aSign != bSign)
253*1da177e4SLinus Torvalds 		return aSign && ((bits32) ((a | b) << 1) != 0);
254*1da177e4SLinus Torvalds 	return (a != b) && (aSign ^ (a < b));
255*1da177e4SLinus Torvalds }
256*1da177e4SLinus Torvalds 
257*1da177e4SLinus Torvalds static inline flag extractFloat64Sign(float64 a)
258*1da177e4SLinus Torvalds {
259*1da177e4SLinus Torvalds 	return a >> 63;
260*1da177e4SLinus Torvalds }
261*1da177e4SLinus Torvalds 
262*1da177e4SLinus Torvalds static inline flag float64_eq_nocheck(float64 a, float64 b)
263*1da177e4SLinus Torvalds {
264*1da177e4SLinus Torvalds 	return (a == b) || ((bits64) ((a | b) << 1) == 0);
265*1da177e4SLinus Torvalds }
266*1da177e4SLinus Torvalds 
267*1da177e4SLinus Torvalds static inline flag float64_lt_nocheck(float64 a, float64 b)
268*1da177e4SLinus Torvalds {
269*1da177e4SLinus Torvalds 	flag aSign, bSign;
270*1da177e4SLinus Torvalds 
271*1da177e4SLinus Torvalds 	aSign = extractFloat64Sign(a);
272*1da177e4SLinus Torvalds 	bSign = extractFloat64Sign(b);
273*1da177e4SLinus Torvalds 	if (aSign != bSign)
274*1da177e4SLinus Torvalds 		return aSign && ((bits64) ((a | b) << 1) != 0);
275*1da177e4SLinus Torvalds 	return (a != b) && (aSign ^ (a < b));
276*1da177e4SLinus Torvalds }
277*1da177e4SLinus Torvalds 
278*1da177e4SLinus Torvalds #endif
279