]> git.proxmox.com Git - mirror_qemu.git/blame - fpu/softfloat-native.c
use constants for TLB handling (Thiemo Seufer)
[mirror_qemu.git] / fpu / softfloat-native.c
CommitLineData
158142c2
FB
1/* Native implementation of soft float functions. Only a single status
2 context is supported */
3#include "softfloat.h"
4#include <math.h>
5
6void set_float_rounding_mode(int val STATUS_PARAM)
7{
8 STATUS(float_rounding_mode) = val;
9#if defined(_BSD) && !defined(__APPLE__)
10 fpsetround(val);
11#elif defined(__arm__)
12 /* nothing to do */
13#else
14 fesetround(val);
15#endif
16}
17
18#ifdef FLOATX80
19void set_floatx80_rounding_precision(int val STATUS_PARAM)
20{
21 STATUS(floatx80_rounding_precision) = val;
22}
23#endif
24
25#if defined(_BSD)
1b2b0af5
FB
26#define lrint(d) ((long)rint(d))
27#define llrint(d) ((long long)rint(d))
158142c2
FB
28#endif
29
30#if defined(__powerpc__)
31
32/* correct (but slow) PowerPC rint() (glibc version is incorrect) */
33double qemu_rint(double x)
34{
35 double y = 4503599627370496.0;
36 if (fabs(x) >= y)
37 return x;
38 if (x < 0)
39 y = -y;
40 y = (x + y) - y;
41 if (y == 0.0)
42 y = copysign(y, x);
43 return y;
44}
45
46#define rint qemu_rint
47#endif
48
49/*----------------------------------------------------------------------------
50| Software IEC/IEEE integer-to-floating-point conversion routines.
51*----------------------------------------------------------------------------*/
52float32 int32_to_float32(int v STATUS_PARAM)
53{
54 return (float32)v;
55}
56
57float64 int32_to_float64(int v STATUS_PARAM)
58{
59 return (float64)v;
60}
61
62#ifdef FLOATX80
63floatx80 int32_to_floatx80(int v STATUS_PARAM)
64{
65 return (floatx80)v;
66}
67#endif
68float32 int64_to_float32( int64_t v STATUS_PARAM)
69{
70 return (float32)v;
71}
72float64 int64_to_float64( int64_t v STATUS_PARAM)
73{
74 return (float64)v;
75}
76#ifdef FLOATX80
77floatx80 int64_to_floatx80( int64_t v STATUS_PARAM)
78{
79 return (floatx80)v;
80}
81#endif
82
1b2b0af5
FB
83/* XXX: this code implements the x86 behaviour, not the IEEE one. */
84#if HOST_LONG_BITS == 32
85static inline int long_to_int32(long a)
86{
87 return a;
88}
89#else
90static inline int long_to_int32(long a)
91{
92 if (a != (int32_t)a)
93 a = 0x80000000;
94 return a;
95}
96#endif
97
158142c2
FB
98/*----------------------------------------------------------------------------
99| Software IEC/IEEE single-precision conversion routines.
100*----------------------------------------------------------------------------*/
101int float32_to_int32( float32 a STATUS_PARAM)
102{
1b2b0af5 103 return long_to_int32(lrintf(a));
158142c2
FB
104}
105int float32_to_int32_round_to_zero( float32 a STATUS_PARAM)
106{
107 return (int)a;
108}
109int64_t float32_to_int64( float32 a STATUS_PARAM)
110{
111 return llrintf(a);
112}
113
114int64_t float32_to_int64_round_to_zero( float32 a STATUS_PARAM)
115{
116 return (int64_t)a;
117}
118
119float64 float32_to_float64( float32 a STATUS_PARAM)
120{
121 return a;
122}
123#ifdef FLOATX80
124floatx80 float32_to_floatx80( float32 a STATUS_PARAM)
125{
126 return a;
127}
128#endif
129
130/*----------------------------------------------------------------------------
131| Software IEC/IEEE single-precision operations.
132*----------------------------------------------------------------------------*/
133float32 float32_round_to_int( float32 a STATUS_PARAM)
134{
135 return rintf(a);
136}
137
b109f9f8
FB
138float32 float32_rem( float32 a, float32 b STATUS_PARAM)
139{
140 return remainderf(a, b);
141}
142
158142c2
FB
143float32 float32_sqrt( float32 a STATUS_PARAM)
144{
145 return sqrtf(a);
146}
b109f9f8
FB
147char float32_compare( float32 a, float32 b STATUS_PARAM )
148{
149 if (a < b) {
150 return -1;
151 } else if (a == b) {
152 return 0;
153 } else if (a > b) {
154 return 1;
155 } else {
156 return 2;
157 }
158}
159char float32_compare_quiet( float32 a, float32 b STATUS_PARAM )
160{
161 if (isless(a, b)) {
162 return -1;
163 } else if (a == b) {
164 return 0;
165 } else if (isgreater(a, b)) {
166 return 1;
167 } else {
168 return 2;
169 }
170}
158142c2
FB
171char float32_is_signaling_nan( float32 a1)
172{
173 float32u u;
174 uint32_t a;
175 u.f = a1;
176 a = u.i;
177 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
178}
179
180/*----------------------------------------------------------------------------
181| Software IEC/IEEE double-precision conversion routines.
182*----------------------------------------------------------------------------*/
183int float64_to_int32( float64 a STATUS_PARAM)
184{
1b2b0af5 185 return long_to_int32(lrint(a));
158142c2
FB
186}
187int float64_to_int32_round_to_zero( float64 a STATUS_PARAM)
188{
189 return (int)a;
190}
191int64_t float64_to_int64( float64 a STATUS_PARAM)
192{
193 return llrint(a);
194}
195int64_t float64_to_int64_round_to_zero( float64 a STATUS_PARAM)
196{
197 return (int64_t)a;
198}
199float32 float64_to_float32( float64 a STATUS_PARAM)
200{
201 return a;
202}
203#ifdef FLOATX80
204floatx80 float64_to_floatx80( float64 a STATUS_PARAM)
205{
206 return a;
207}
208#endif
209#ifdef FLOAT128
210float128 float64_to_float128( float64 a STATUS_PARAM)
211{
212 return a;
213}
214#endif
215
216/*----------------------------------------------------------------------------
217| Software IEC/IEEE double-precision operations.
218*----------------------------------------------------------------------------*/
219float64 float64_round_to_int( float64 a STATUS_PARAM )
220{
221#if defined(__arm__)
222 switch(STATUS(float_rounding_mode)) {
223 default:
224 case float_round_nearest_even:
225 asm("rndd %0, %1" : "=f" (a) : "f"(a));
226 break;
227 case float_round_down:
228 asm("rnddm %0, %1" : "=f" (a) : "f"(a));
229 break;
230 case float_round_up:
231 asm("rnddp %0, %1" : "=f" (a) : "f"(a));
232 break;
233 case float_round_to_zero:
234 asm("rnddz %0, %1" : "=f" (a) : "f"(a));
235 break;
236 }
237#else
238 return rint(a);
239#endif
240}
241
b109f9f8
FB
242float64 float64_rem( float64 a, float64 b STATUS_PARAM)
243{
244 return remainder(a, b);
245}
246
158142c2
FB
247float64 float64_sqrt( float64 a STATUS_PARAM)
248{
249 return sqrt(a);
250}
b109f9f8
FB
251char float64_compare( float64 a, float64 b STATUS_PARAM )
252{
253 if (a < b) {
254 return -1;
255 } else if (a == b) {
256 return 0;
257 } else if (a > b) {
258 return 1;
259 } else {
260 return 2;
261 }
262}
263char float64_compare_quiet( float64 a, float64 b STATUS_PARAM )
264{
265 if (isless(a, b)) {
266 return -1;
267 } else if (a == b) {
268 return 0;
269 } else if (isgreater(a, b)) {
270 return 1;
271 } else {
272 return 2;
273 }
274}
158142c2
FB
275char float64_is_signaling_nan( float64 a1)
276{
277 float64u u;
278 uint64_t a;
279 u.f = a1;
280 a = u.i;
281 return
282 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
283 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
284
285}
286
287#ifdef FLOATX80
288
289/*----------------------------------------------------------------------------
290| Software IEC/IEEE extended double-precision conversion routines.
291*----------------------------------------------------------------------------*/
292int floatx80_to_int32( floatx80 a STATUS_PARAM)
293{
1b2b0af5 294 return long_to_int32(lrintl(a));
158142c2
FB
295}
296int floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM)
297{
298 return (int)a;
299}
300int64_t floatx80_to_int64( floatx80 a STATUS_PARAM)
301{
302 return llrintl(a);
303}
304int64_t floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM)
305{
306 return (int64_t)a;
307}
308float32 floatx80_to_float32( floatx80 a STATUS_PARAM)
309{
310 return a;
311}
312float64 floatx80_to_float64( floatx80 a STATUS_PARAM)
313{
314 return a;
315}
316
317/*----------------------------------------------------------------------------
318| Software IEC/IEEE extended double-precision operations.
319*----------------------------------------------------------------------------*/
320floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
321{
322 return rintl(a);
323}
b109f9f8
FB
324floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM)
325{
326 return remainderl(a, b);
327}
158142c2
FB
328floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM)
329{
330 return sqrtl(a);
331}
b109f9f8
FB
332char floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
333{
334 if (a < b) {
335 return -1;
336 } else if (a == b) {
337 return 0;
338 } else if (a > b) {
339 return 1;
340 } else {
341 return 2;
342 }
343}
344char floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
345{
346 if (isless(a, b)) {
347 return -1;
348 } else if (a == b) {
349 return 0;
350 } else if (isgreater(a, b)) {
351 return 1;
352 } else {
353 return 2;
354 }
355}
158142c2
FB
356char floatx80_is_signaling_nan( floatx80 a1)
357{
358 floatx80u u;
359 u.f = a1;
360 return ( ( u.i.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( u.i.low<<1 );
361}
362
363#endif