1 | /*
|
---|
2 | * TCC runtime library for arm64.
|
---|
3 | *
|
---|
4 | * Copyright (c) 2015 Edmund Grimley Evans
|
---|
5 | *
|
---|
6 | * Copying and distribution of this file, with or without modification,
|
---|
7 | * are permitted in any medium without royalty provided the copyright
|
---|
8 | * notice and this notice are preserved. This file is offered as-is,
|
---|
9 | * without any warranty.
|
---|
10 | */
|
---|
11 |
|
---|
12 | #ifdef __TINYC__
|
---|
13 | typedef signed char int8_t;
|
---|
14 | typedef unsigned char uint8_t;
|
---|
15 | typedef short int16_t;
|
---|
16 | typedef unsigned short uint16_t;
|
---|
17 | typedef int int32_t;
|
---|
18 | typedef unsigned uint32_t;
|
---|
19 | typedef long long int64_t;
|
---|
20 | typedef unsigned long long uint64_t;
|
---|
21 | void *memcpy(void*,void*,__SIZE_TYPE__);
|
---|
22 | #else
|
---|
23 | #include <stdint.h>
|
---|
24 | #include <string.h>
|
---|
25 | #endif
|
---|
26 |
|
---|
27 | void __clear_cache(void *beg, void *end)
|
---|
28 | {
|
---|
29 | __arm64_clear_cache(beg, end);
|
---|
30 | }
|
---|
31 |
|
---|
32 | typedef struct {
|
---|
33 | uint64_t x0, x1;
|
---|
34 | } u128_t;
|
---|
35 |
|
---|
36 | static long double f3_zero(int sgn)
|
---|
37 | {
|
---|
38 | long double f;
|
---|
39 | u128_t x = { 0, (uint64_t)sgn << 63 };
|
---|
40 | memcpy(&f, &x, 16);
|
---|
41 | return f;
|
---|
42 | }
|
---|
43 |
|
---|
44 | static long double f3_infinity(int sgn)
|
---|
45 | {
|
---|
46 | long double f;
|
---|
47 | u128_t x = { 0, (uint64_t)sgn << 63 | 0x7fff000000000000 };
|
---|
48 | memcpy(&f, &x, 16);
|
---|
49 | return f;
|
---|
50 | }
|
---|
51 |
|
---|
52 | static long double f3_NaN(void)
|
---|
53 | {
|
---|
54 | long double f;
|
---|
55 | #if 0
|
---|
56 | // ARM's default NaN usually has just the top fraction bit set:
|
---|
57 | u128_t x = { 0, 0x7fff800000000000 };
|
---|
58 | #else
|
---|
59 | // GCC's library sets all fraction bits:
|
---|
60 | u128_t x = { -1, 0x7fffffffffffffff };
|
---|
61 | #endif
|
---|
62 | memcpy(&f, &x, 16);
|
---|
63 | return f;
|
---|
64 | }
|
---|
65 |
|
---|
66 | static int fp3_convert_NaN(long double *f, int sgn, u128_t mnt)
|
---|
67 | {
|
---|
68 | u128_t x = { mnt.x0,
|
---|
69 | mnt.x1 | 0x7fff800000000000 | (uint64_t)sgn << 63 };
|
---|
70 | memcpy(f, &x, 16);
|
---|
71 | return 1;
|
---|
72 | }
|
---|
73 |
|
---|
74 | static int fp3_detect_NaNs(long double *f,
|
---|
75 | int a_sgn, int a_exp, u128_t a,
|
---|
76 | int b_sgn, int b_exp, u128_t b)
|
---|
77 | {
|
---|
78 | // Detect signalling NaNs:
|
---|
79 | if (a_exp == 32767 && (a.x0 | a.x1 << 16) && !(a.x1 >> 47 & 1))
|
---|
80 | return fp3_convert_NaN(f, a_sgn, a);
|
---|
81 | if (b_exp == 32767 && (b.x0 | b.x1 << 16) && !(b.x1 >> 47 & 1))
|
---|
82 | return fp3_convert_NaN(f, b_sgn, b);
|
---|
83 |
|
---|
84 | // Detect quiet NaNs:
|
---|
85 | if (a_exp == 32767 && (a.x0 | a.x1 << 16))
|
---|
86 | return fp3_convert_NaN(f, a_sgn, a);
|
---|
87 | if (b_exp == 32767 && (b.x0 | b.x1 << 16))
|
---|
88 | return fp3_convert_NaN(f, b_sgn, b);
|
---|
89 |
|
---|
90 | return 0;
|
---|
91 | }
|
---|
92 |
|
---|
93 | static void f3_unpack(int *sgn, int32_t *exp, u128_t *mnt, long double f)
|
---|
94 | {
|
---|
95 | u128_t x;
|
---|
96 | memcpy(&x, &f, 16);
|
---|
97 | *sgn = x.x1 >> 63;
|
---|
98 | *exp = x.x1 >> 48 & 32767;
|
---|
99 | x.x1 = x.x1 << 16 >> 16;
|
---|
100 | if (*exp)
|
---|
101 | x.x1 |= (uint64_t)1 << 48;
|
---|
102 | else
|
---|
103 | *exp = 1;
|
---|
104 | *mnt = x;
|
---|
105 | }
|
---|
106 |
|
---|
107 | static u128_t f3_normalise(int32_t *exp, u128_t mnt)
|
---|
108 | {
|
---|
109 | int sh;
|
---|
110 | if (!(mnt.x0 | mnt.x1))
|
---|
111 | return mnt;
|
---|
112 | if (!mnt.x1) {
|
---|
113 | mnt.x1 = mnt.x0;
|
---|
114 | mnt.x0 = 0;
|
---|
115 | *exp -= 64;
|
---|
116 | }
|
---|
117 | for (sh = 32; sh; sh >>= 1) {
|
---|
118 | if (!(mnt.x1 >> (64 - sh))) {
|
---|
119 | mnt.x1 = mnt.x1 << sh | mnt.x0 >> (64 - sh);
|
---|
120 | mnt.x0 = mnt.x0 << sh;
|
---|
121 | *exp -= sh;
|
---|
122 | }
|
---|
123 | }
|
---|
124 | return mnt;
|
---|
125 | }
|
---|
126 |
|
---|
127 | static u128_t f3_sticky_shift(int32_t sh, u128_t x)
|
---|
128 | {
|
---|
129 | if (sh >= 128) {
|
---|
130 | x.x0 = !!(x.x0 | x.x1);
|
---|
131 | x.x1 = 0;
|
---|
132 | return x;
|
---|
133 | }
|
---|
134 | if (sh >= 64) {
|
---|
135 | x.x0 = x.x1 | !!x.x0;
|
---|
136 | x.x1 = 0;
|
---|
137 | sh -= 64;
|
---|
138 | }
|
---|
139 | if (sh > 0) {
|
---|
140 | x.x0 = x.x0 >> sh | x.x1 << (64 - sh) | !!(x.x0 << (64 - sh));
|
---|
141 | x.x1 = x.x1 >> sh;
|
---|
142 | }
|
---|
143 | return x;
|
---|
144 | }
|
---|
145 |
|
---|
146 | static long double f3_round(int sgn, int32_t exp, u128_t x)
|
---|
147 | {
|
---|
148 | long double f;
|
---|
149 | int error;
|
---|
150 |
|
---|
151 | if (exp > 0) {
|
---|
152 | x = f3_sticky_shift(13, x);
|
---|
153 | }
|
---|
154 | else {
|
---|
155 | x = f3_sticky_shift(14 - exp, x);
|
---|
156 | exp = 0;
|
---|
157 | }
|
---|
158 |
|
---|
159 | error = x.x0 & 3;
|
---|
160 | x.x0 = x.x0 >> 2 | x.x1 << 62;
|
---|
161 | x.x1 = x.x1 >> 2;
|
---|
162 |
|
---|
163 | if (error == 3 || ((error == 2) & (x.x0 & 1))) {
|
---|
164 | if (!++x.x0) {
|
---|
165 | ++x.x1;
|
---|
166 | if (x.x1 == (uint64_t)1 << 48)
|
---|
167 | exp = 1;
|
---|
168 | else if (x.x1 == (uint64_t)1 << 49) {
|
---|
169 | ++exp;
|
---|
170 | x.x0 = x.x0 >> 1 | x.x1 << 63;
|
---|
171 | x.x1 = x.x1 >> 1;
|
---|
172 | }
|
---|
173 | }
|
---|
174 | }
|
---|
175 |
|
---|
176 | if (exp >= 32767)
|
---|
177 | return f3_infinity(sgn);
|
---|
178 |
|
---|
179 | x.x1 = x.x1 << 16 >> 16 | (uint64_t)exp << 48 | (uint64_t)sgn << 63;
|
---|
180 | memcpy(&f, &x, 16);
|
---|
181 | return f;
|
---|
182 | }
|
---|
183 |
|
---|
184 | static long double f3_add(long double fa, long double fb, int neg)
|
---|
185 | {
|
---|
186 | u128_t a, b, x;
|
---|
187 | int32_t a_exp, b_exp, x_exp;
|
---|
188 | int a_sgn, b_sgn, x_sgn;
|
---|
189 | long double fx;
|
---|
190 |
|
---|
191 | f3_unpack(&a_sgn, &a_exp, &a, fa);
|
---|
192 | f3_unpack(&b_sgn, &b_exp, &b, fb);
|
---|
193 |
|
---|
194 | if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
|
---|
195 | return fx;
|
---|
196 |
|
---|
197 | b_sgn ^= neg;
|
---|
198 |
|
---|
199 | // Handle infinities and zeroes:
|
---|
200 | if (a_exp == 32767 && b_exp == 32767 && a_sgn != b_sgn)
|
---|
201 | return f3_NaN();
|
---|
202 | if (a_exp == 32767)
|
---|
203 | return f3_infinity(a_sgn);
|
---|
204 | if (b_exp == 32767)
|
---|
205 | return f3_infinity(b_sgn);
|
---|
206 | if (!(a.x0 | a.x1 | b.x0 | b.x1))
|
---|
207 | return f3_zero(a_sgn & b_sgn);
|
---|
208 |
|
---|
209 | a.x1 = a.x1 << 3 | a.x0 >> 61;
|
---|
210 | a.x0 = a.x0 << 3;
|
---|
211 | b.x1 = b.x1 << 3 | b.x0 >> 61;
|
---|
212 | b.x0 = b.x0 << 3;
|
---|
213 |
|
---|
214 | if (a_exp <= b_exp) {
|
---|
215 | a = f3_sticky_shift(b_exp - a_exp, a);
|
---|
216 | a_exp = b_exp;
|
---|
217 | }
|
---|
218 | else {
|
---|
219 | b = f3_sticky_shift(a_exp - b_exp, b);
|
---|
220 | b_exp = a_exp;
|
---|
221 | }
|
---|
222 |
|
---|
223 | x_sgn = a_sgn;
|
---|
224 | x_exp = a_exp;
|
---|
225 | if (a_sgn == b_sgn) {
|
---|
226 | x.x0 = a.x0 + b.x0;
|
---|
227 | x.x1 = a.x1 + b.x1 + (x.x0 < a.x0);
|
---|
228 | }
|
---|
229 | else {
|
---|
230 | x.x0 = a.x0 - b.x0;
|
---|
231 | x.x1 = a.x1 - b.x1 - (x.x0 > a.x0);
|
---|
232 | if (x.x1 >> 63) {
|
---|
233 | x_sgn ^= 1;
|
---|
234 | x.x0 = -x.x0;
|
---|
235 | x.x1 = -x.x1 - !!x.x0;
|
---|
236 | }
|
---|
237 | }
|
---|
238 |
|
---|
239 | if (!(x.x0 | x.x1))
|
---|
240 | return f3_zero(0);
|
---|
241 |
|
---|
242 | x = f3_normalise(&x_exp, x);
|
---|
243 |
|
---|
244 | return f3_round(x_sgn, x_exp + 12, x);
|
---|
245 | }
|
---|
246 |
|
---|
247 | long double __addtf3(long double a, long double b)
|
---|
248 | {
|
---|
249 | return f3_add(a, b, 0);
|
---|
250 | }
|
---|
251 |
|
---|
252 | long double __subtf3(long double a, long double b)
|
---|
253 | {
|
---|
254 | return f3_add(a, b, 1);
|
---|
255 | }
|
---|
256 |
|
---|
257 | long double __multf3(long double fa, long double fb)
|
---|
258 | {
|
---|
259 | u128_t a, b, x;
|
---|
260 | int32_t a_exp, b_exp, x_exp;
|
---|
261 | int a_sgn, b_sgn, x_sgn;
|
---|
262 | long double fx;
|
---|
263 |
|
---|
264 | f3_unpack(&a_sgn, &a_exp, &a, fa);
|
---|
265 | f3_unpack(&b_sgn, &b_exp, &b, fb);
|
---|
266 |
|
---|
267 | if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
|
---|
268 | return fx;
|
---|
269 |
|
---|
270 | // Handle infinities and zeroes:
|
---|
271 | if ((a_exp == 32767 && !(b.x0 | b.x1)) ||
|
---|
272 | (b_exp == 32767 && !(a.x0 | a.x1)))
|
---|
273 | return f3_NaN();
|
---|
274 | if (a_exp == 32767 || b_exp == 32767)
|
---|
275 | return f3_infinity(a_sgn ^ b_sgn);
|
---|
276 | if (!(a.x0 | a.x1) || !(b.x0 | b.x1))
|
---|
277 | return f3_zero(a_sgn ^ b_sgn);
|
---|
278 |
|
---|
279 | a = f3_normalise(&a_exp, a);
|
---|
280 | b = f3_normalise(&b_exp, b);
|
---|
281 |
|
---|
282 | x_sgn = a_sgn ^ b_sgn;
|
---|
283 | x_exp = a_exp + b_exp - 16352;
|
---|
284 |
|
---|
285 | {
|
---|
286 | // Convert to base (1 << 30), discarding bottom 6 bits, which are zero,
|
---|
287 | // so there are (32, 30, 30, 30) bits in (a3, a2, a1, a0):
|
---|
288 | uint64_t a0 = a.x0 << 28 >> 34;
|
---|
289 | uint64_t b0 = b.x0 << 28 >> 34;
|
---|
290 | uint64_t a1 = a.x0 >> 36 | a.x1 << 62 >> 34;
|
---|
291 | uint64_t b1 = b.x0 >> 36 | b.x1 << 62 >> 34;
|
---|
292 | uint64_t a2 = a.x1 << 32 >> 34;
|
---|
293 | uint64_t b2 = b.x1 << 32 >> 34;
|
---|
294 | uint64_t a3 = a.x1 >> 32;
|
---|
295 | uint64_t b3 = b.x1 >> 32;
|
---|
296 | // Use 16 small multiplications and additions that do not overflow:
|
---|
297 | uint64_t x0 = a0 * b0;
|
---|
298 | uint64_t x1 = (x0 >> 30) + a0 * b1 + a1 * b0;
|
---|
299 | uint64_t x2 = (x1 >> 30) + a0 * b2 + a1 * b1 + a2 * b0;
|
---|
300 | uint64_t x3 = (x2 >> 30) + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
|
---|
301 | uint64_t x4 = (x3 >> 30) + a1 * b3 + a2 * b2 + a3 * b1;
|
---|
302 | uint64_t x5 = (x4 >> 30) + a2 * b3 + a3 * b2;
|
---|
303 | uint64_t x6 = (x5 >> 30) + a3 * b3;
|
---|
304 | // We now have (64, 30, 30, ...) bits in (x6, x5, x4, ...).
|
---|
305 | // Take the top 128 bits, setting bottom bit if any lower bits were set:
|
---|
306 | uint64_t y0 = (x5 << 34 | x4 << 34 >> 30 | x3 << 34 >> 60 |
|
---|
307 | !!(x3 << 38 | (x2 | x1 | x0) << 34));
|
---|
308 | uint64_t y1 = x6;
|
---|
309 | // Top bit may be zero. Renormalise:
|
---|
310 | if (!(y1 >> 63)) {
|
---|
311 | y1 = y1 << 1 | y0 >> 63;
|
---|
312 | y0 = y0 << 1;
|
---|
313 | --x_exp;
|
---|
314 | }
|
---|
315 | x.x0 = y0;
|
---|
316 | x.x1 = y1;
|
---|
317 | }
|
---|
318 |
|
---|
319 | return f3_round(x_sgn, x_exp, x);
|
---|
320 | }
|
---|
321 |
|
---|
322 | long double __divtf3(long double fa, long double fb)
|
---|
323 | {
|
---|
324 | u128_t a, b, x;
|
---|
325 | int32_t a_exp, b_exp, x_exp;
|
---|
326 | int a_sgn, b_sgn, x_sgn, i;
|
---|
327 | long double fx;
|
---|
328 |
|
---|
329 | f3_unpack(&a_sgn, &a_exp, &a, fa);
|
---|
330 | f3_unpack(&b_sgn, &b_exp, &b, fb);
|
---|
331 |
|
---|
332 | if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
|
---|
333 | return fx;
|
---|
334 |
|
---|
335 | // Handle infinities and zeroes:
|
---|
336 | if ((a_exp == 32767 && b_exp == 32767) ||
|
---|
337 | (!(a.x0 | a.x1) && !(b.x0 | b.x1)))
|
---|
338 | return f3_NaN();
|
---|
339 | if (a_exp == 32767 || !(b.x0 | b.x1))
|
---|
340 | return f3_infinity(a_sgn ^ b_sgn);
|
---|
341 | if (!(a.x0 | a.x1) || b_exp == 32767)
|
---|
342 | return f3_zero(a_sgn ^ b_sgn);
|
---|
343 |
|
---|
344 | a = f3_normalise(&a_exp, a);
|
---|
345 | b = f3_normalise(&b_exp, b);
|
---|
346 |
|
---|
347 | x_sgn = a_sgn ^ b_sgn;
|
---|
348 | x_exp = a_exp - b_exp + 16395;
|
---|
349 |
|
---|
350 | a.x0 = a.x0 >> 1 | a.x1 << 63;
|
---|
351 | a.x1 = a.x1 >> 1;
|
---|
352 | b.x0 = b.x0 >> 1 | b.x1 << 63;
|
---|
353 | b.x1 = b.x1 >> 1;
|
---|
354 | x.x0 = 0;
|
---|
355 | x.x1 = 0;
|
---|
356 | for (i = 0; i < 116; i++) {
|
---|
357 | x.x1 = x.x1 << 1 | x.x0 >> 63;
|
---|
358 | x.x0 = x.x0 << 1;
|
---|
359 | if (a.x1 > b.x1 || (a.x1 == b.x1 && a.x0 >= b.x0)) {
|
---|
360 | a.x1 = a.x1 - b.x1 - (a.x0 < b.x0);
|
---|
361 | a.x0 = a.x0 - b.x0;
|
---|
362 | x.x0 |= 1;
|
---|
363 | }
|
---|
364 | a.x1 = a.x1 << 1 | a.x0 >> 63;
|
---|
365 | a.x0 = a.x0 << 1;
|
---|
366 | }
|
---|
367 | x.x0 |= !!(a.x0 | a.x1);
|
---|
368 |
|
---|
369 | x = f3_normalise(&x_exp, x);
|
---|
370 |
|
---|
371 | return f3_round(x_sgn, x_exp, x);
|
---|
372 | }
|
---|
373 |
|
---|
374 | long double __extendsftf2(float f)
|
---|
375 | {
|
---|
376 | long double fx;
|
---|
377 | u128_t x;
|
---|
378 | uint32_t a;
|
---|
379 | uint64_t aa;
|
---|
380 | memcpy(&a, &f, 4);
|
---|
381 | aa = a;
|
---|
382 | x.x0 = 0;
|
---|
383 | if (!(a << 1))
|
---|
384 | x.x1 = aa << 32;
|
---|
385 | else if (a << 1 >> 24 == 255)
|
---|
386 | x.x1 = (0x7fff000000000000 | aa >> 31 << 63 | aa << 41 >> 16 |
|
---|
387 | (uint64_t)!!(a << 9) << 47);
|
---|
388 | else
|
---|
389 | x.x1 = (aa >> 31 << 63 | ((aa >> 23 & 255) + 16256) << 48 |
|
---|
390 | aa << 41 >> 16);
|
---|
391 | memcpy(&fx, &x, 16);
|
---|
392 | return fx;
|
---|
393 | }
|
---|
394 |
|
---|
395 | long double __extenddftf2(double f)
|
---|
396 | {
|
---|
397 | long double fx;
|
---|
398 | u128_t x;
|
---|
399 | uint64_t a;
|
---|
400 | memcpy(&a, &f, 8);
|
---|
401 | x.x0 = a << 60;
|
---|
402 | if (!(a << 1))
|
---|
403 | x.x1 = a;
|
---|
404 | else if (a << 1 >> 53 == 2047)
|
---|
405 | x.x1 = (0x7fff000000000000 | a >> 63 << 63 | a << 12 >> 16 |
|
---|
406 | (uint64_t)!!(a << 12) << 47);
|
---|
407 | else
|
---|
408 | x.x1 = a >> 63 << 63 | ((a >> 52 & 2047) + 15360) << 48 | a << 12 >> 16;
|
---|
409 | memcpy(&fx, &x, 16);
|
---|
410 | return fx;
|
---|
411 | }
|
---|
412 |
|
---|
413 | float __trunctfsf2(long double f)
|
---|
414 | {
|
---|
415 | u128_t mnt;
|
---|
416 | int32_t exp;
|
---|
417 | int sgn;
|
---|
418 | uint32_t x;
|
---|
419 | float fx;
|
---|
420 |
|
---|
421 | f3_unpack(&sgn, &exp, &mnt, f);
|
---|
422 |
|
---|
423 | if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
|
---|
424 | x = 0x7fc00000 | (uint32_t)sgn << 31 | (mnt.x1 >> 25 & 0x007fffff);
|
---|
425 | else if (exp > 16510)
|
---|
426 | x = 0x7f800000 | (uint32_t)sgn << 31;
|
---|
427 | else if (exp < 16233)
|
---|
428 | x = (uint32_t)sgn << 31;
|
---|
429 | else {
|
---|
430 | exp -= 16257;
|
---|
431 | x = mnt.x1 >> 23 | !!(mnt.x0 | mnt.x1 << 41);
|
---|
432 | if (exp < 0) {
|
---|
433 | x = x >> -exp | !!(x << (32 + exp));
|
---|
434 | exp = 0;
|
---|
435 | }
|
---|
436 | if ((x & 3) == 3 || (x & 7) == 6)
|
---|
437 | x += 4;
|
---|
438 | x = ((x >> 2) + (exp << 23)) | (uint32_t)sgn << 31;
|
---|
439 | }
|
---|
440 | memcpy(&fx, &x, 4);
|
---|
441 | return fx;
|
---|
442 | }
|
---|
443 |
|
---|
444 | double __trunctfdf2(long double f)
|
---|
445 | {
|
---|
446 | u128_t mnt;
|
---|
447 | int32_t exp;
|
---|
448 | int sgn;
|
---|
449 | uint64_t x;
|
---|
450 | double fx;
|
---|
451 |
|
---|
452 | f3_unpack(&sgn, &exp, &mnt, f);
|
---|
453 |
|
---|
454 | if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
|
---|
455 | x = (0x7ff8000000000000 | (uint64_t)sgn << 63 |
|
---|
456 | mnt.x1 << 16 >> 12 | mnt.x0 >> 60);
|
---|
457 | else if (exp > 17406)
|
---|
458 | x = 0x7ff0000000000000 | (uint64_t)sgn << 63;
|
---|
459 | else if (exp < 15308)
|
---|
460 | x = (uint64_t)sgn << 63;
|
---|
461 | else {
|
---|
462 | exp -= 15361;
|
---|
463 | x = mnt.x1 << 6 | mnt.x0 >> 58 | !!(mnt.x0 << 6);
|
---|
464 | if (exp < 0) {
|
---|
465 | x = x >> -exp | !!(x << (64 + exp));
|
---|
466 | exp = 0;
|
---|
467 | }
|
---|
468 | if ((x & 3) == 3 || (x & 7) == 6)
|
---|
469 | x += 4;
|
---|
470 | x = ((x >> 2) + ((uint64_t)exp << 52)) | (uint64_t)sgn << 63;
|
---|
471 | }
|
---|
472 | memcpy(&fx, &x, 8);
|
---|
473 | return fx;
|
---|
474 | }
|
---|
475 |
|
---|
476 | int32_t __fixtfsi(long double fa)
|
---|
477 | {
|
---|
478 | u128_t a;
|
---|
479 | int32_t a_exp;
|
---|
480 | int a_sgn;
|
---|
481 | int32_t x;
|
---|
482 | f3_unpack(&a_sgn, &a_exp, &a, fa);
|
---|
483 | if (a_exp < 16369)
|
---|
484 | return 0;
|
---|
485 | if (a_exp > 16413)
|
---|
486 | return a_sgn ? -0x80000000 : 0x7fffffff;
|
---|
487 | x = a.x1 >> (16431 - a_exp);
|
---|
488 | return a_sgn ? -x : x;
|
---|
489 | }
|
---|
490 |
|
---|
491 | int64_t __fixtfdi(long double fa)
|
---|
492 | {
|
---|
493 | u128_t a;
|
---|
494 | int32_t a_exp;
|
---|
495 | int a_sgn;
|
---|
496 | int64_t x;
|
---|
497 | f3_unpack(&a_sgn, &a_exp, &a, fa);
|
---|
498 | if (a_exp < 16383)
|
---|
499 | return 0;
|
---|
500 | if (a_exp > 16445)
|
---|
501 | return a_sgn ? -0x8000000000000000 : 0x7fffffffffffffff;
|
---|
502 | x = (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
|
---|
503 | return a_sgn ? -x : x;
|
---|
504 | }
|
---|
505 |
|
---|
506 | uint32_t __fixunstfsi(long double fa)
|
---|
507 | {
|
---|
508 | u128_t a;
|
---|
509 | int32_t a_exp;
|
---|
510 | int a_sgn;
|
---|
511 | f3_unpack(&a_sgn, &a_exp, &a, fa);
|
---|
512 | if (a_sgn || a_exp < 16369)
|
---|
513 | return 0;
|
---|
514 | if (a_exp > 16414)
|
---|
515 | return -1;
|
---|
516 | return a.x1 >> (16431 - a_exp);
|
---|
517 | }
|
---|
518 |
|
---|
519 | uint64_t __fixunstfdi(long double fa)
|
---|
520 | {
|
---|
521 | u128_t a;
|
---|
522 | int32_t a_exp;
|
---|
523 | int a_sgn;
|
---|
524 | f3_unpack(&a_sgn, &a_exp, &a, fa);
|
---|
525 | if (a_sgn || a_exp < 16383)
|
---|
526 | return 0;
|
---|
527 | if (a_exp > 16446)
|
---|
528 | return -1;
|
---|
529 | return (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
|
---|
530 | }
|
---|
531 |
|
---|
532 | long double __floatsitf(int32_t a)
|
---|
533 | {
|
---|
534 | int sgn = 0;
|
---|
535 | int exp = 16414;
|
---|
536 | uint32_t mnt = a;
|
---|
537 | u128_t x = { 0, 0 };
|
---|
538 | long double f;
|
---|
539 | int i;
|
---|
540 | if (a) {
|
---|
541 | if (a < 0) {
|
---|
542 | sgn = 1;
|
---|
543 | mnt = -mnt;
|
---|
544 | }
|
---|
545 | for (i = 16; i; i >>= 1)
|
---|
546 | if (!(mnt >> (32 - i))) {
|
---|
547 | mnt <<= i;
|
---|
548 | exp -= i;
|
---|
549 | }
|
---|
550 | x.x1 = ((uint64_t)sgn << 63 | (uint64_t)exp << 48 |
|
---|
551 | (uint64_t)(mnt << 1) << 16);
|
---|
552 | }
|
---|
553 | memcpy(&f, &x, 16);
|
---|
554 | return f;
|
---|
555 | }
|
---|
556 |
|
---|
557 | long double __floatditf(int64_t a)
|
---|
558 | {
|
---|
559 | int sgn = 0;
|
---|
560 | int exp = 16446;
|
---|
561 | uint64_t mnt = a;
|
---|
562 | u128_t x = { 0, 0 };
|
---|
563 | long double f;
|
---|
564 | int i;
|
---|
565 | if (a) {
|
---|
566 | if (a < 0) {
|
---|
567 | sgn = 1;
|
---|
568 | mnt = -mnt;
|
---|
569 | }
|
---|
570 | for (i = 32; i; i >>= 1)
|
---|
571 | if (!(mnt >> (64 - i))) {
|
---|
572 | mnt <<= i;
|
---|
573 | exp -= i;
|
---|
574 | }
|
---|
575 | x.x0 = mnt << 49;
|
---|
576 | x.x1 = (uint64_t)sgn << 63 | (uint64_t)exp << 48 | mnt << 1 >> 16;
|
---|
577 | }
|
---|
578 | memcpy(&f, &x, 16);
|
---|
579 | return f;
|
---|
580 | }
|
---|
581 |
|
---|
582 | long double __floatunsitf(uint32_t a)
|
---|
583 | {
|
---|
584 | int exp = 16414;
|
---|
585 | uint32_t mnt = a;
|
---|
586 | u128_t x = { 0, 0 };
|
---|
587 | long double f;
|
---|
588 | int i;
|
---|
589 | if (a) {
|
---|
590 | for (i = 16; i; i >>= 1)
|
---|
591 | if (!(mnt >> (32 - i))) {
|
---|
592 | mnt <<= i;
|
---|
593 | exp -= i;
|
---|
594 | }
|
---|
595 | x.x1 = (uint64_t)exp << 48 | (uint64_t)(mnt << 1) << 16;
|
---|
596 | }
|
---|
597 | memcpy(&f, &x, 16);
|
---|
598 | return f;
|
---|
599 | }
|
---|
600 |
|
---|
601 | long double __floatunditf(uint64_t a)
|
---|
602 | {
|
---|
603 | int exp = 16446;
|
---|
604 | uint64_t mnt = a;
|
---|
605 | u128_t x = { 0, 0 };
|
---|
606 | long double f;
|
---|
607 | int i;
|
---|
608 | if (a) {
|
---|
609 | for (i = 32; i; i >>= 1)
|
---|
610 | if (!(mnt >> (64 - i))) {
|
---|
611 | mnt <<= i;
|
---|
612 | exp -= i;
|
---|
613 | }
|
---|
614 | x.x0 = mnt << 49;
|
---|
615 | x.x1 = (uint64_t)exp << 48 | mnt << 1 >> 16;
|
---|
616 | }
|
---|
617 | memcpy(&f, &x, 16);
|
---|
618 | return f;
|
---|
619 | }
|
---|
620 |
|
---|
621 | static int f3_cmp(long double fa, long double fb)
|
---|
622 | {
|
---|
623 | u128_t a, b;
|
---|
624 | memcpy(&a, &fa, 16);
|
---|
625 | memcpy(&b, &fb, 16);
|
---|
626 | return (!(a.x0 | a.x1 << 1 | b.x0 | b.x1 << 1) ? 0 :
|
---|
627 | ((a.x1 << 1 >> 49 == 0x7fff && (a.x0 | a.x1 << 16)) ||
|
---|
628 | (b.x1 << 1 >> 49 == 0x7fff && (b.x0 | b.x1 << 16))) ? 2 :
|
---|
629 | a.x1 >> 63 != b.x1 >> 63 ? (int)(b.x1 >> 63) - (int)(a.x1 >> 63) :
|
---|
630 | a.x1 < b.x1 ? (int)(a.x1 >> 63 << 1) - 1 :
|
---|
631 | a.x1 > b.x1 ? 1 - (int)(a.x1 >> 63 << 1) :
|
---|
632 | a.x0 < b.x0 ? (int)(a.x1 >> 63 << 1) - 1 :
|
---|
633 | b.x0 < a.x0 ? 1 - (int)(a.x1 >> 63 << 1) : 0);
|
---|
634 | }
|
---|
635 |
|
---|
636 | int __eqtf2(long double a, long double b)
|
---|
637 | {
|
---|
638 | return !!f3_cmp(a, b);
|
---|
639 | }
|
---|
640 |
|
---|
641 | int __netf2(long double a, long double b)
|
---|
642 | {
|
---|
643 | return !!f3_cmp(a, b);
|
---|
644 | }
|
---|
645 |
|
---|
646 | int __lttf2(long double a, long double b)
|
---|
647 | {
|
---|
648 | return f3_cmp(a, b);
|
---|
649 | }
|
---|
650 |
|
---|
651 | int __letf2(long double a, long double b)
|
---|
652 | {
|
---|
653 | return f3_cmp(a, b);
|
---|
654 | }
|
---|
655 |
|
---|
656 | int __gttf2(long double a, long double b)
|
---|
657 | {
|
---|
658 | return -f3_cmp(b, a);
|
---|
659 | }
|
---|
660 |
|
---|
661 | int __getf2(long double a, long double b)
|
---|
662 | {
|
---|
663 | return -f3_cmp(b, a);
|
---|
664 | }
|
---|