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