]> git.proxmox.com Git - qemu.git/blame - fpu/softfloat-native.h
bFLT 64-bit host fix.
[qemu.git] / fpu / softfloat-native.h
CommitLineData
158142c2
FB
1/* Native implementation of soft float functions */
2#include <math.h>
38cfa06c
FB
3
4#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
158142c2 5#include <ieeefp.h>
38cfa06c 6#define fabsf(f) ((float)fabs(f))
158142c2
FB
7#else
8#include <fenv.h>
9#endif
38cfa06c
FB
10
11/*
12 * Define some C99-7.12.3 classification macros and
13 * some C99-.12.4 for Solaris systems OS less than 10,
14 * or Solaris 10 systems running GCC 3.x or less.
15 * Solaris 10 with GCC4 does not need these macros as they
16 * are defined in <iso/math_c99.h> with a compiler directive
17 */
18#if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ( ( HOST_SOLARIS >= 10 ) && ( __GNUC__ <= 4) ))
19/*
20 * C99 7.12.3 classification macros
21 * and
22 * C99 7.12.14 comparison macros
23 *
24 * ... do not work on Solaris 10 using GNU CC 3.4.x.
25 * Try to workaround the missing / broken C99 math macros.
26 */
27
28#define isnormal(x) (fpclass(x) >= FP_NZERO)
29#define isgreater(x, y) ((!unordered(x, y)) && ((x) > (y)))
30#define isgreaterequal(x, y) ((!unordered(x, y)) && ((x) >= (y)))
31#define isless(x, y) ((!unordered(x, y)) && ((x) < (y)))
32#define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y)))
33#define isunordered(x,y) unordered(x, y)
ec530c81 34#endif
158142c2
FB
35
36typedef float float32;
37typedef double float64;
38#ifdef FLOATX80
39typedef long double floatx80;
40#endif
41
42typedef union {
43 float32 f;
44 uint32_t i;
45} float32u;
46typedef union {
47 float64 f;
48 uint64_t i;
49} float64u;
50#ifdef FLOATX80
51typedef union {
52 floatx80 f;
53 struct {
54 uint64_t low;
55 uint16_t high;
56 } i;
57} floatx80u;
58#endif
59
60/*----------------------------------------------------------------------------
61| Software IEC/IEEE floating-point rounding mode.
62*----------------------------------------------------------------------------*/
38cfa06c 63#if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
158142c2
FB
64enum {
65 float_round_nearest_even = FP_RN,
7918bf47
PB
66 float_round_down = FP_RM,
67 float_round_up = FP_RP,
68 float_round_to_zero = FP_RZ
158142c2
FB
69};
70#elif defined(__arm__)
71enum {
72 float_round_nearest_even = 0,
73 float_round_down = 1,
74 float_round_up = 2,
75 float_round_to_zero = 3
76};
77#else
78enum {
79 float_round_nearest_even = FE_TONEAREST,
80 float_round_down = FE_DOWNWARD,
81 float_round_up = FE_UPWARD,
82 float_round_to_zero = FE_TOWARDZERO
83};
84#endif
85
86typedef struct float_status {
87 signed char float_rounding_mode;
88#ifdef FLOATX80
89 signed char floatx80_rounding_precision;
90#endif
91} float_status;
92
93void set_float_rounding_mode(int val STATUS_PARAM);
94#ifdef FLOATX80
95void set_floatx80_rounding_precision(int val STATUS_PARAM);
96#endif
97
98/*----------------------------------------------------------------------------
99| Software IEC/IEEE integer-to-floating-point conversion routines.
100*----------------------------------------------------------------------------*/
101float32 int32_to_float32( int STATUS_PARAM);
102float64 int32_to_float64( int STATUS_PARAM);
103#ifdef FLOATX80
104floatx80 int32_to_floatx80( int STATUS_PARAM);
105#endif
106#ifdef FLOAT128
107float128 int32_to_float128( int STATUS_PARAM);
108#endif
109float32 int64_to_float32( int64_t STATUS_PARAM);
110float64 int64_to_float64( int64_t STATUS_PARAM);
111#ifdef FLOATX80
112floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
113#endif
114#ifdef FLOAT128
115float128 int64_to_float128( int64_t STATUS_PARAM);
116#endif
117
118/*----------------------------------------------------------------------------
119| Software IEC/IEEE single-precision conversion routines.
120*----------------------------------------------------------------------------*/
121int float32_to_int32( float32 STATUS_PARAM);
122int float32_to_int32_round_to_zero( float32 STATUS_PARAM);
123int64_t float32_to_int64( float32 STATUS_PARAM);
124int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM);
125float64 float32_to_float64( float32 STATUS_PARAM);
126#ifdef FLOATX80
127floatx80 float32_to_floatx80( float32 STATUS_PARAM);
128#endif
129#ifdef FLOAT128
130float128 float32_to_float128( float32 STATUS_PARAM);
131#endif
132
133/*----------------------------------------------------------------------------
134| Software IEC/IEEE single-precision operations.
135*----------------------------------------------------------------------------*/
136float32 float32_round_to_int( float32 STATUS_PARAM);
137INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM)
138{
139 return a + b;
140}
141INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM)
142{
143 return a - b;
144}
145INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM)
146{
147 return a * b;
148}
149INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
150{
151 return a / b;
152}
153float32 float32_rem( float32, float32 STATUS_PARAM);
154float32 float32_sqrt( float32 STATUS_PARAM);
155INLINE char float32_eq( float32 a, float32 b STATUS_PARAM)
156{
158142c2
FB
157 return a == b;
158}
159INLINE char float32_le( float32 a, float32 b STATUS_PARAM)
160{
161 return a <= b;
162}
163INLINE char float32_lt( float32 a, float32 b STATUS_PARAM)
164{
165 return a < b;
166}
167INLINE char float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
168{
b109f9f8 169 return a <= b && a >= b;
158142c2
FB
170}
171INLINE char float32_le_quiet( float32 a, float32 b STATUS_PARAM)
172{
173 return islessequal(a, b);
174}
175INLINE char float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
176{
177 return isless(a, b);
178}
b109f9f8
FB
179INLINE char float32_unordered( float32 a, float32 b STATUS_PARAM)
180{
181 return isunordered(a, b);
182
183}
184char float32_compare( float32, float32 STATUS_PARAM );
185char float32_compare_quiet( float32, float32 STATUS_PARAM );
158142c2
FB
186char float32_is_signaling_nan( float32 );
187
188INLINE float32 float32_abs(float32 a)
189{
190 return fabsf(a);
191}
192
193INLINE float32 float32_chs(float32 a)
194{
195 return -a;
196}
197
198/*----------------------------------------------------------------------------
199| Software IEC/IEEE double-precision conversion routines.
200*----------------------------------------------------------------------------*/
201int float64_to_int32( float64 STATUS_PARAM );
202int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
203int64_t float64_to_int64( float64 STATUS_PARAM );
204int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
205float32 float64_to_float32( float64 STATUS_PARAM );
206#ifdef FLOATX80
207floatx80 float64_to_floatx80( float64 STATUS_PARAM );
208#endif
209#ifdef FLOAT128
210float128 float64_to_float128( float64 STATUS_PARAM );
211#endif
212
213/*----------------------------------------------------------------------------
214| Software IEC/IEEE double-precision operations.
215*----------------------------------------------------------------------------*/
216float64 float64_round_to_int( float64 STATUS_PARAM );
217INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
218{
219 return a + b;
220}
221INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
222{
223 return a - b;
224}
225INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
226{
227 return a * b;
228}
229INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
230{
231 return a / b;
232}
233float64 float64_rem( float64, float64 STATUS_PARAM );
234float64 float64_sqrt( float64 STATUS_PARAM );
235INLINE char float64_eq( float64 a, float64 b STATUS_PARAM)
236{
237 return a == b;
238}
239INLINE char float64_le( float64 a, float64 b STATUS_PARAM)
240{
241 return a <= b;
242}
243INLINE char float64_lt( float64 a, float64 b STATUS_PARAM)
244{
245 return a < b;
246}
247INLINE char float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
248{
b109f9f8 249 return a <= b && a >= b;
158142c2
FB
250}
251INLINE char float64_le_quiet( float64 a, float64 b STATUS_PARAM)
252{
253 return islessequal(a, b);
254}
255INLINE char float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
256{
257 return isless(a, b);
258
259}
b109f9f8
FB
260INLINE char float64_unordered( float64 a, float64 b STATUS_PARAM)
261{
262 return isunordered(a, b);
263
264}
265char float64_compare( float64, float64 STATUS_PARAM );
266char float64_compare_quiet( float64, float64 STATUS_PARAM );
158142c2
FB
267char float64_is_signaling_nan( float64 );
268
269INLINE float64 float64_abs(float64 a)
270{
271 return fabs(a);
272}
273
274INLINE float64 float64_chs(float64 a)
275{
276 return -a;
277}
278
279#ifdef FLOATX80
280
281/*----------------------------------------------------------------------------
282| Software IEC/IEEE extended double-precision conversion routines.
283*----------------------------------------------------------------------------*/
284int floatx80_to_int32( floatx80 STATUS_PARAM );
285int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
286int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
287int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
288float32 floatx80_to_float32( floatx80 STATUS_PARAM );
289float64 floatx80_to_float64( floatx80 STATUS_PARAM );
290#ifdef FLOAT128
291float128 floatx80_to_float128( floatx80 STATUS_PARAM );
292#endif
293
294/*----------------------------------------------------------------------------
295| Software IEC/IEEE extended double-precision operations.
296*----------------------------------------------------------------------------*/
297floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
298INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
299{
300 return a + b;
301}
302INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
303{
304 return a - b;
305}
306INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
307{
308 return a * b;
309}
310INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
311{
312 return a / b;
313}
314floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
315floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
316INLINE char floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
317{
318 return a == b;
319}
320INLINE char floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
321{
322 return a <= b;
323}
324INLINE char floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
325{
326 return a < b;
327}
328INLINE char floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
329{
b109f9f8 330 return a <= b && a >= b;
158142c2
FB
331}
332INLINE char floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
333{
334 return islessequal(a, b);
335}
336INLINE char floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
337{
338 return isless(a, b);
339
340}
b109f9f8
FB
341INLINE char floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
342{
343 return isunordered(a, b);
344
345}
346char floatx80_compare( floatx80, floatx80 STATUS_PARAM );
347char floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
158142c2
FB
348char floatx80_is_signaling_nan( floatx80 );
349
350INLINE floatx80 floatx80_abs(floatx80 a)
351{
352 return fabsl(a);
353}
354
355INLINE floatx80 floatx80_chs(floatx80 a)
356{
357 return -a;
358}
359#endif