xref: /openbmc/linux/arch/arm/nwfpe/softfloat.h (revision bedf142b8bba4331ed93161292a4ce4f8cde7308)
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 *bedf142bSLennert Buytenhek typedef u32 float32;
55 *bedf142bSLennert Buytenhek typedef u64 float64;
56 1da177e4SLinus Torvalds typedef struct {
57 *bedf142bSLennert Buytenhek #ifdef __ARMEB__
58 *bedf142bSLennert Buytenhek     u16 __padding;
59 *bedf142bSLennert Buytenhek     u16 high;
60 *bedf142bSLennert Buytenhek #else
61 *bedf142bSLennert Buytenhek     u16 high;
62 *bedf142bSLennert Buytenhek     u16 __padding;
63 *bedf142bSLennert Buytenhek #endif
64 *bedf142bSLennert Buytenhek     u64 low;
65 1da177e4SLinus Torvalds } floatx80;
66 1da177e4SLinus Torvalds 
67 1da177e4SLinus Torvalds /*
68 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
69 1da177e4SLinus Torvalds Software IEC/IEEE floating-point underflow tininess-detection mode.
70 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
71 1da177e4SLinus Torvalds */
72 1da177e4SLinus Torvalds extern signed char float_detect_tininess;
73 1da177e4SLinus Torvalds enum {
74 1da177e4SLinus Torvalds     float_tininess_after_rounding  = 0,
75 1da177e4SLinus Torvalds     float_tininess_before_rounding = 1
76 1da177e4SLinus Torvalds };
77 1da177e4SLinus Torvalds 
78 1da177e4SLinus Torvalds /*
79 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
80 1da177e4SLinus Torvalds Software IEC/IEEE floating-point rounding mode.
81 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
82 1da177e4SLinus Torvalds */
83 f148af25SRichard Purdie //extern int8 float_rounding_mode;
84 1da177e4SLinus Torvalds enum {
85 1da177e4SLinus Torvalds     float_round_nearest_even = 0,
86 1da177e4SLinus Torvalds     float_round_to_zero      = 1,
87 1da177e4SLinus Torvalds     float_round_down         = 2,
88 1da177e4SLinus Torvalds     float_round_up           = 3
89 1da177e4SLinus Torvalds };
90 1da177e4SLinus Torvalds 
91 1da177e4SLinus Torvalds /*
92 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
93 1da177e4SLinus Torvalds Software IEC/IEEE floating-point exception flags.
94 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
95 1da177e4SLinus Torvalds enum {
96 1da177e4SLinus Torvalds     float_flag_inexact   =  1,
97 1da177e4SLinus Torvalds     float_flag_underflow =  2,
98 1da177e4SLinus Torvalds     float_flag_overflow  =  4,
99 1da177e4SLinus Torvalds     float_flag_divbyzero =  8,
100 1da177e4SLinus Torvalds     float_flag_invalid   = 16
101 1da177e4SLinus Torvalds };
102 1da177e4SLinus Torvalds 
103 1da177e4SLinus Torvalds ScottB: November 4, 1998
104 1da177e4SLinus Torvalds Changed the enumeration to match the bit order in the FPA11.
105 1da177e4SLinus Torvalds */
106 1da177e4SLinus Torvalds 
107 1da177e4SLinus Torvalds enum {
108 1da177e4SLinus Torvalds     float_flag_invalid   =  1,
109 1da177e4SLinus Torvalds     float_flag_divbyzero =  2,
110 1da177e4SLinus Torvalds     float_flag_overflow  =  4,
111 1da177e4SLinus Torvalds     float_flag_underflow =  8,
112 1da177e4SLinus Torvalds     float_flag_inexact   = 16
113 1da177e4SLinus Torvalds };
114 1da177e4SLinus Torvalds 
115 1da177e4SLinus Torvalds /*
116 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
117 1da177e4SLinus Torvalds Routine to raise any or all of the software IEC/IEEE floating-point
118 1da177e4SLinus Torvalds exception flags.
119 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
120 1da177e4SLinus Torvalds */
121 1da177e4SLinus Torvalds void float_raise( signed char );
122 1da177e4SLinus Torvalds 
123 1da177e4SLinus Torvalds /*
124 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
125 1da177e4SLinus Torvalds Software IEC/IEEE integer-to-floating-point conversion routines.
126 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
127 1da177e4SLinus Torvalds */
128 f148af25SRichard Purdie float32 int32_to_float32( struct roundingData *, signed int );
129 1da177e4SLinus Torvalds float64 int32_to_float64( signed int );
130 1da177e4SLinus Torvalds #ifdef FLOATX80
131 1da177e4SLinus Torvalds floatx80 int32_to_floatx80( signed int );
132 1da177e4SLinus Torvalds #endif
133 1da177e4SLinus Torvalds 
134 1da177e4SLinus Torvalds /*
135 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
136 1da177e4SLinus Torvalds Software IEC/IEEE single-precision conversion routines.
137 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
138 1da177e4SLinus Torvalds */
139 f148af25SRichard Purdie signed int float32_to_int32( struct roundingData *, float32 );
140 1da177e4SLinus Torvalds signed int float32_to_int32_round_to_zero( float32 );
141 1da177e4SLinus Torvalds float64 float32_to_float64( float32 );
142 1da177e4SLinus Torvalds #ifdef FLOATX80
143 1da177e4SLinus Torvalds floatx80 float32_to_floatx80( float32 );
144 1da177e4SLinus Torvalds #endif
145 1da177e4SLinus Torvalds 
146 1da177e4SLinus Torvalds /*
147 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
148 1da177e4SLinus Torvalds Software IEC/IEEE single-precision operations.
149 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
150 1da177e4SLinus Torvalds */
151 f148af25SRichard Purdie float32 float32_round_to_int( struct roundingData*, float32 );
152 f148af25SRichard Purdie float32 float32_add( struct roundingData *, float32, float32 );
153 f148af25SRichard Purdie float32 float32_sub( struct roundingData *, float32, float32 );
154 f148af25SRichard Purdie float32 float32_mul( struct roundingData *, float32, float32 );
155 f148af25SRichard Purdie float32 float32_div( struct roundingData *, float32, float32 );
156 f148af25SRichard Purdie float32 float32_rem( struct roundingData *, float32, float32 );
157 f148af25SRichard Purdie float32 float32_sqrt( struct roundingData*, float32 );
158 1da177e4SLinus Torvalds char float32_eq( float32, float32 );
159 1da177e4SLinus Torvalds char float32_le( float32, float32 );
160 1da177e4SLinus Torvalds char float32_lt( float32, float32 );
161 1da177e4SLinus Torvalds char float32_eq_signaling( float32, float32 );
162 1da177e4SLinus Torvalds char float32_le_quiet( float32, float32 );
163 1da177e4SLinus Torvalds char float32_lt_quiet( float32, float32 );
164 1da177e4SLinus Torvalds char float32_is_signaling_nan( float32 );
165 1da177e4SLinus Torvalds 
166 1da177e4SLinus Torvalds /*
167 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
168 1da177e4SLinus Torvalds Software IEC/IEEE double-precision conversion routines.
169 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
170 1da177e4SLinus Torvalds */
171 f148af25SRichard Purdie signed int float64_to_int32( struct roundingData *, float64 );
172 1da177e4SLinus Torvalds signed int float64_to_int32_round_to_zero( float64 );
173 f148af25SRichard Purdie float32 float64_to_float32( struct roundingData *, float64 );
174 1da177e4SLinus Torvalds #ifdef FLOATX80
175 1da177e4SLinus Torvalds floatx80 float64_to_floatx80( float64 );
176 1da177e4SLinus Torvalds #endif
177 1da177e4SLinus Torvalds 
178 1da177e4SLinus Torvalds /*
179 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
180 1da177e4SLinus Torvalds Software IEC/IEEE double-precision operations.
181 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
182 1da177e4SLinus Torvalds */
183 f148af25SRichard Purdie float64 float64_round_to_int( struct roundingData *, float64 );
184 f148af25SRichard Purdie float64 float64_add( struct roundingData *, float64, float64 );
185 f148af25SRichard Purdie float64 float64_sub( struct roundingData *, float64, float64 );
186 f148af25SRichard Purdie float64 float64_mul( struct roundingData *, float64, float64 );
187 f148af25SRichard Purdie float64 float64_div( struct roundingData *, float64, float64 );
188 f148af25SRichard Purdie float64 float64_rem( struct roundingData *, float64, float64 );
189 f148af25SRichard Purdie float64 float64_sqrt( struct roundingData *, float64 );
190 1da177e4SLinus Torvalds char float64_eq( float64, float64 );
191 1da177e4SLinus Torvalds char float64_le( float64, float64 );
192 1da177e4SLinus Torvalds char float64_lt( float64, float64 );
193 1da177e4SLinus Torvalds char float64_eq_signaling( float64, float64 );
194 1da177e4SLinus Torvalds char float64_le_quiet( float64, float64 );
195 1da177e4SLinus Torvalds char float64_lt_quiet( float64, float64 );
196 1da177e4SLinus Torvalds char float64_is_signaling_nan( float64 );
197 1da177e4SLinus Torvalds 
198 1da177e4SLinus Torvalds #ifdef FLOATX80
199 1da177e4SLinus Torvalds 
200 1da177e4SLinus Torvalds /*
201 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
202 1da177e4SLinus Torvalds Software IEC/IEEE extended double-precision conversion routines.
203 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
204 1da177e4SLinus Torvalds */
205 f148af25SRichard Purdie signed int floatx80_to_int32( struct roundingData *, floatx80 );
206 1da177e4SLinus Torvalds signed int floatx80_to_int32_round_to_zero( floatx80 );
207 f148af25SRichard Purdie float32 floatx80_to_float32( struct roundingData *, floatx80 );
208 f148af25SRichard Purdie float64 floatx80_to_float64( struct roundingData *, floatx80 );
209 1da177e4SLinus Torvalds 
210 1da177e4SLinus Torvalds /*
211 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
212 1da177e4SLinus Torvalds Software IEC/IEEE extended double-precision operations.
213 1da177e4SLinus Torvalds -------------------------------------------------------------------------------
214 1da177e4SLinus Torvalds */
215 f148af25SRichard Purdie floatx80 floatx80_round_to_int( struct roundingData *, floatx80 );
216 f148af25SRichard Purdie floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 );
217 f148af25SRichard Purdie floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 );
218 f148af25SRichard Purdie floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 );
219 f148af25SRichard Purdie floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 );
220 f148af25SRichard Purdie floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 );
221 f148af25SRichard Purdie floatx80 floatx80_sqrt( struct roundingData *, floatx80 );
222 1da177e4SLinus Torvalds char floatx80_eq( floatx80, floatx80 );
223 1da177e4SLinus Torvalds char floatx80_le( floatx80, floatx80 );
224 1da177e4SLinus Torvalds char floatx80_lt( floatx80, floatx80 );
225 1da177e4SLinus Torvalds char floatx80_eq_signaling( floatx80, floatx80 );
226 1da177e4SLinus Torvalds char floatx80_le_quiet( floatx80, floatx80 );
227 1da177e4SLinus Torvalds char floatx80_lt_quiet( floatx80, floatx80 );
228 1da177e4SLinus Torvalds char floatx80_is_signaling_nan( floatx80 );
229 1da177e4SLinus Torvalds 
230 1da177e4SLinus Torvalds #endif
231 1da177e4SLinus Torvalds 
232 1da177e4SLinus Torvalds static inline flag extractFloat32Sign(float32 a)
233 1da177e4SLinus Torvalds {
234 1da177e4SLinus Torvalds 	return a >> 31;
235 1da177e4SLinus Torvalds }
236 1da177e4SLinus Torvalds 
237 1da177e4SLinus Torvalds static inline flag float32_eq_nocheck(float32 a, float32 b)
238 1da177e4SLinus Torvalds {
239 1da177e4SLinus Torvalds 	return (a == b) || ((bits32) ((a | b) << 1) == 0);
240 1da177e4SLinus Torvalds }
241 1da177e4SLinus Torvalds 
242 1da177e4SLinus Torvalds static inline flag float32_lt_nocheck(float32 a, float32 b)
243 1da177e4SLinus Torvalds {
244 1da177e4SLinus Torvalds 	flag aSign, bSign;
245 1da177e4SLinus Torvalds 
246 1da177e4SLinus Torvalds 	aSign = extractFloat32Sign(a);
247 1da177e4SLinus Torvalds 	bSign = extractFloat32Sign(b);
248 1da177e4SLinus Torvalds 	if (aSign != bSign)
249 1da177e4SLinus Torvalds 		return aSign && ((bits32) ((a | b) << 1) != 0);
250 1da177e4SLinus Torvalds 	return (a != b) && (aSign ^ (a < b));
251 1da177e4SLinus Torvalds }
252 1da177e4SLinus Torvalds 
253 1da177e4SLinus Torvalds static inline flag extractFloat64Sign(float64 a)
254 1da177e4SLinus Torvalds {
255 1da177e4SLinus Torvalds 	return a >> 63;
256 1da177e4SLinus Torvalds }
257 1da177e4SLinus Torvalds 
258 1da177e4SLinus Torvalds static inline flag float64_eq_nocheck(float64 a, float64 b)
259 1da177e4SLinus Torvalds {
260 1da177e4SLinus Torvalds 	return (a == b) || ((bits64) ((a | b) << 1) == 0);
261 1da177e4SLinus Torvalds }
262 1da177e4SLinus Torvalds 
263 1da177e4SLinus Torvalds static inline flag float64_lt_nocheck(float64 a, float64 b)
264 1da177e4SLinus Torvalds {
265 1da177e4SLinus Torvalds 	flag aSign, bSign;
266 1da177e4SLinus Torvalds 
267 1da177e4SLinus Torvalds 	aSign = extractFloat64Sign(a);
268 1da177e4SLinus Torvalds 	bSign = extractFloat64Sign(b);
269 1da177e4SLinus Torvalds 	if (aSign != bSign)
270 1da177e4SLinus Torvalds 		return aSign && ((bits64) ((a | b) << 1) != 0);
271 1da177e4SLinus Torvalds 	return (a != b) && (aSign ^ (a < b));
272 1da177e4SLinus Torvalds }
273 1da177e4SLinus Torvalds 
274 6ec5e7f3SBen Dooks extern flag float32_is_nan( float32 a );
275 6ec5e7f3SBen Dooks extern flag float64_is_nan( float64 a );
276 6ec5e7f3SBen Dooks 
277 1da177e4SLinus Torvalds #endif
278