1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "qemu/osdep.h"
23#include "softfloat.h"
24#include "fpu/softfloat-macros.h"
25#include "softfloat_fpsp_tables.h"
26
27#define pi_exp 0x4000
28#define piby2_exp 0x3FFF
29#define pi_sig UINT64_C(0xc90fdaa22168c235)
30
31static floatx80 propagateFloatx80NaNOneArg(floatx80 a, float_status *status)
32{
33 if (floatx80_is_signaling_nan(a, status)) {
34 float_raise(float_flag_invalid, status);
35 a = floatx80_silence_nan(a, status);
36 }
37
38 if (status->default_nan_mode) {
39 return floatx80_default_nan(status);
40 }
41
42 return a;
43}
44
45
46
47
48
49
50floatx80 floatx80_getman(floatx80 a, float_status *status)
51{
52 bool aSign;
53 int32_t aExp;
54 uint64_t aSig;
55
56 aSig = extractFloatx80Frac(a);
57 aExp = extractFloatx80Exp(a);
58 aSign = extractFloatx80Sign(a);
59
60 if (aExp == 0x7FFF) {
61 if ((uint64_t) (aSig << 1)) {
62 return propagateFloatx80NaNOneArg(a , status);
63 }
64 float_raise(float_flag_invalid , status);
65 return floatx80_default_nan(status);
66 }
67
68 if (aExp == 0) {
69 if (aSig == 0) {
70 return packFloatx80(aSign, 0, 0);
71 }
72 normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
73 }
74
75 return roundAndPackFloatx80(status->floatx80_rounding_precision, aSign,
76 0x3FFF, aSig, 0, status);
77}
78
79
80
81
82
83
84floatx80 floatx80_getexp(floatx80 a, float_status *status)
85{
86 bool aSign;
87 int32_t aExp;
88 uint64_t aSig;
89
90 aSig = extractFloatx80Frac(a);
91 aExp = extractFloatx80Exp(a);
92 aSign = extractFloatx80Sign(a);
93
94 if (aExp == 0x7FFF) {
95 if ((uint64_t) (aSig << 1)) {
96 return propagateFloatx80NaNOneArg(a , status);
97 }
98 float_raise(float_flag_invalid , status);
99 return floatx80_default_nan(status);
100 }
101
102 if (aExp == 0) {
103 if (aSig == 0) {
104 return packFloatx80(aSign, 0, 0);
105 }
106 normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
107 }
108
109 return int32_to_floatx80(aExp - 0x3FFF, status);
110}
111
112
113
114
115
116
117
118
119
120floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status)
121{
122 bool aSign, bSign;
123 int32_t aExp, bExp, shiftCount;
124 uint64_t aSig, bSig;
125
126 aSig = extractFloatx80Frac(a);
127 aExp = extractFloatx80Exp(a);
128 aSign = extractFloatx80Sign(a);
129 bSig = extractFloatx80Frac(b);
130 bExp = extractFloatx80Exp(b);
131 bSign = extractFloatx80Sign(b);
132
133 if (bExp == 0x7FFF) {
134 if ((uint64_t) (bSig << 1) ||
135 ((aExp == 0x7FFF) && (uint64_t) (aSig << 1))) {
136 return propagateFloatx80NaN(a, b, status);
137 }
138 float_raise(float_flag_invalid , status);
139 return floatx80_default_nan(status);
140 }
141 if (aExp == 0x7FFF) {
142 if ((uint64_t) (aSig << 1)) {
143 return propagateFloatx80NaN(a, b, status);
144 }
145 return packFloatx80(aSign, floatx80_infinity.high,
146 floatx80_infinity.low);
147 }
148 if (aExp == 0) {
149 if (aSig == 0) {
150 return packFloatx80(aSign, 0, 0);
151 }
152 if (bExp < 0x3FFF) {
153 return a;
154 }
155 normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
156 }
157
158 if (bExp < 0x3FFF) {
159 return a;
160 }
161
162 if (0x400F < bExp) {
163 aExp = bSign ? -0x6001 : 0xE000;
164 return roundAndPackFloatx80(status->floatx80_rounding_precision,
165 aSign, aExp, aSig, 0, status);
166 }
167
168 shiftCount = 0x403E - bExp;
169 bSig >>= shiftCount;
170 aExp = bSign ? (aExp - bSig) : (aExp + bSig);
171
172 return roundAndPackFloatx80(status->floatx80_rounding_precision,
173 aSign, aExp, aSig, 0, status);
174}
175
176floatx80 floatx80_move(floatx80 a, float_status *status)
177{
178 bool aSign;
179 int32_t aExp;
180 uint64_t aSig;
181
182 aSig = extractFloatx80Frac(a);
183 aExp = extractFloatx80Exp(a);
184 aSign = extractFloatx80Sign(a);
185
186 if (aExp == 0x7FFF) {
187 if ((uint64_t)(aSig << 1)) {
188 return propagateFloatx80NaNOneArg(a, status);
189 }
190 return a;
191 }
192 if (aExp == 0) {
193 if (aSig == 0) {
194 return a;
195 }
196 normalizeRoundAndPackFloatx80(status->floatx80_rounding_precision,
197 aSign, aExp, aSig, 0, status);
198 }
199 return roundAndPackFloatx80(status->floatx80_rounding_precision, aSign,
200 aExp, aSig, 0, status);
201}
202
203
204
205
206
207
208#define one_exp 0x3FFF
209#define one_sig UINT64_C(0x8000000000000000)
210
211
212
213
214
215static int32_t floatx80_make_compact(int32_t aExp, uint64_t aSig)
216{
217 return (aExp << 16) | (aSig >> 48);
218}
219
220
221
222
223
224floatx80 floatx80_lognp1(floatx80 a, float_status *status)
225{
226 bool aSign;
227 int32_t aExp;
228 uint64_t aSig, fSig;
229
230 FloatRoundMode user_rnd_mode;
231 FloatX80RoundPrec user_rnd_prec;
232
233 int32_t compact, j, k;
234 floatx80 fp0, fp1, fp2, fp3, f, logof2, klog2, saveu;
235
236 aSig = extractFloatx80Frac(a);
237 aExp = extractFloatx80Exp(a);
238 aSign = extractFloatx80Sign(a);
239
240 if (aExp == 0x7FFF) {
241 if ((uint64_t) (aSig << 1)) {
242 propagateFloatx80NaNOneArg(a, status);
243 }
244 if (aSign) {
245 float_raise(float_flag_invalid, status);
246 return floatx80_default_nan(status);
247 }
248 return packFloatx80(0, floatx80_infinity.high, floatx80_infinity.low);
249 }
250
251 if (aExp == 0 && aSig == 0) {
252 return packFloatx80(aSign, 0, 0);
253 }
254
255 if (aSign && aExp >= one_exp) {
256 if (aExp == one_exp && aSig == one_sig) {
257 float_raise(float_flag_divbyzero, status);
258 return packFloatx80(aSign, floatx80_infinity.high,
259 floatx80_infinity.low);
260 }
261 float_raise(float_flag_invalid, status);
262 return floatx80_default_nan(status);
263 }
264
265 if (aExp < 0x3f99 || (aExp == 0x3f99 && aSig == one_sig)) {
266
267 float_raise(float_flag_inexact, status);
268 return floatx80_move(a, status);
269 }
270
271 user_rnd_mode = status->float_rounding_mode;
272 user_rnd_prec = status->floatx80_rounding_precision;
273 status->float_rounding_mode = float_round_nearest_even;
274 status->floatx80_rounding_precision = floatx80_precision_x;
275
276 compact = floatx80_make_compact(aExp, aSig);
277
278 fp0 = a;
279 fp1 = a;
280
281 fp0 = floatx80_add(fp0, float32_to_floatx80(make_float32(0x3F800000),
282 status), status);
283
284 aExp = extractFloatx80Exp(fp0);
285 aSig = extractFloatx80Frac(fp0);
286
287 compact = floatx80_make_compact(aExp, aSig);
288
289 if (compact < 0x3FFE8000 || compact > 0x3FFFC000) {
290
291 k = aExp - 0x3FFF;
292 fp1 = int32_to_floatx80(k, status);
293
294 fSig = (aSig & UINT64_C(0xFE00000000000000)) | UINT64_C(0x0100000000000000);
295 j = (fSig >> 56) & 0x7E;
296
297 f = packFloatx80(0, 0x3FFF, fSig);
298 fp0 = packFloatx80(0, 0x3FFF, aSig);
299
300 fp0 = floatx80_sub(fp0, f, status);
301
302 lp1cont1:
303
304 fp0 = floatx80_mul(fp0, log_tbl[j], status);
305 logof2 = packFloatx80(0, 0x3FFE, UINT64_C(0xB17217F7D1CF79AC));
306 klog2 = floatx80_mul(fp1, logof2, status);
307 fp2 = floatx80_mul(fp0, fp0, status);
308
309 fp3 = fp2;
310 fp1 = fp2;
311
312 fp1 = floatx80_mul(fp1, float64_to_floatx80(
313 make_float64(0x3FC2499AB5E4040B), status),
314 status);
315 fp2 = floatx80_mul(fp2, float64_to_floatx80(
316 make_float64(0xBFC555B5848CB7DB), status),
317 status);
318 fp1 = floatx80_add(fp1, float64_to_floatx80(
319 make_float64(0x3FC99999987D8730), status),
320 status);
321 fp2 = floatx80_add(fp2, float64_to_floatx80(
322 make_float64(0xBFCFFFFFFF6F7E97), status),
323 status);
324 fp1 = floatx80_mul(fp1, fp3, status);
325 fp2 = floatx80_mul(fp2, fp3, status);
326 fp1 = floatx80_add(fp1, float64_to_floatx80(
327 make_float64(0x3FD55555555555A4), status),
328 status);
329 fp2 = floatx80_add(fp2, float64_to_floatx80(
330 make_float64(0xBFE0000000000008), status),
331 status);
332 fp1 = floatx80_mul(fp1, fp3, status);
333 fp2 = floatx80_mul(fp2, fp3, status);
334 fp1 = floatx80_mul(fp1, fp0, status);
335 fp0 = floatx80_add(fp0, fp2, status);
336
337 fp1 = floatx80_add(fp1, log_tbl[j + 1],
338 status);
339 fp0 = floatx80_add(fp0, fp1, status);
340
341 status->float_rounding_mode = user_rnd_mode;
342 status->floatx80_rounding_precision = user_rnd_prec;
343
344 a = floatx80_add(fp0, klog2, status);
345
346 float_raise(float_flag_inexact, status);
347
348 return a;
349 } else if (compact < 0x3FFEF07D || compact > 0x3FFF8841) {
350
351
352 fSig = (aSig & UINT64_C(0xFE00000000000000)) | UINT64_C(0x0100000000000000);
353 f = packFloatx80(0, 0x3FFF, fSig);
354 j = (fSig >> 56) & 0x7E;
355
356 if (compact >= 0x3FFF8000) {
357
358 fp0 = floatx80_sub(float32_to_floatx80(make_float32(0x3F800000),
359 status), f, status);
360 fp0 = floatx80_add(fp0, fp1, status);
361 fp1 = packFloatx80(0, 0, 0);
362 } else {
363
364 fp0 = floatx80_sub(float32_to_floatx80(make_float32(0x40000000),
365 status), f, status);
366 fp1 = floatx80_add(fp1, fp1, status);
367 fp0 = floatx80_add(fp0, fp1, status);
368 fp1 = packFloatx80(1, one_exp, one_sig);
369 }
370 goto lp1cont1;
371 } else {
372
373 fp1 = floatx80_add(fp1, fp1, status);
374 fp0 = floatx80_add(fp0, float32_to_floatx80(make_float32(0x3F800000),
375 status), status);
376
377
378 fp1 = floatx80_div(fp1, fp0, status);
379 saveu = fp1;
380 fp0 = floatx80_mul(fp1, fp1, status);
381 fp1 = floatx80_mul(fp0, fp0, status);
382
383 fp3 = float64_to_floatx80(make_float64(0x3F175496ADD7DAD6),
384 status);
385 fp2 = float64_to_floatx80(make_float64(0x3F3C71C2FE80C7E0),
386 status);
387 fp3 = floatx80_mul(fp3, fp1, status);
388 fp2 = floatx80_mul(fp2, fp1, status);
389 fp3 = floatx80_add(fp3, float64_to_floatx80(
390 make_float64(0x3F624924928BCCFF), status),
391 status);
392 fp2 = floatx80_add(fp2, float64_to_floatx80(
393 make_float64(0x3F899999999995EC), status),
394 status);
395 fp1 = floatx80_mul(fp1, fp3, status);
396 fp2 = floatx80_mul(fp2, fp0, status);
397 fp1 = floatx80_add(fp1, float64_to_floatx80(
398 make_float64(0x3FB5555555555555), status),
399 status);
400
401 fp0 = floatx80_mul(fp0, saveu, status);
402 fp1 = floatx80_add(fp1, fp2,
403 status);
404 fp0 = floatx80_mul(fp0, fp1,
405 status);
406
407 status->float_rounding_mode = user_rnd_mode;
408 status->floatx80_rounding_precision = user_rnd_prec;
409
410 a = floatx80_add(fp0, saveu, status);
411
412
413 float_raise(float_flag_inexact, status);
414
415
416 return a;
417 }
418}
419
420
421
422
423
424floatx80 floatx80_logn(floatx80 a, float_status *status)
425{
426 bool aSign;
427 int32_t aExp;
428 uint64_t aSig, fSig;
429
430 FloatRoundMode user_rnd_mode;
431 FloatX80RoundPrec user_rnd_prec;
432
433 int32_t compact, j, k, adjk;
434 floatx80 fp0, fp1, fp2, fp3, f, logof2, klog2, saveu;
435
436 aSig = extractFloatx80Frac(a);
437 aExp = extractFloatx80Exp(a);
438 aSign = extractFloatx80Sign(a);
439
440 if (aExp == 0x7FFF) {
441 if ((uint64_t) (aSig << 1)) {
442 propagateFloatx80NaNOneArg(a, status);
443 }
444 if (aSign == 0) {
445 return packFloatx80(0, floatx80_infinity.high,
446 floatx80_infinity.low);
447 }
448 }
449
450 adjk = 0;
451
452 if (aExp == 0) {
453 if (aSig == 0) {
454 float_raise(float_flag_divbyzero, status);
455 return packFloatx80(1, floatx80_infinity.high,
456 floatx80_infinity.low);
457 }
458 if ((aSig & one_sig) == 0) {
459 normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
460 adjk = -100;
461 aExp += 100;
462 a = packFloatx80(aSign, aExp, aSig);
463 }
464 }
465
466 if (aSign) {
467 float_raise(float_flag_invalid, status);
468 return floatx80_default_nan(status);
469 }
470
471 user_rnd_mode = status->float_rounding_mode;
472 user_rnd_prec = status->floatx80_rounding_precision;
473 status->float_rounding_mode = float_round_nearest_even;
474 status->floatx80_rounding_precision = floatx80_precision_x;
475
476 compact = floatx80_make_compact(aExp, aSig);
477
478 if (compact < 0x3FFEF07D || compact > 0x3FFF8841) {
479
480 k = aExp - 0x3FFF;
481 k += adjk;
482 fp1 = int32_to_floatx80(k, status);
483
484 fSig = (aSig & UINT64_C(0xFE00000000000000)) | UINT64_C(0x0100000000000000);
485 j = (fSig >> 56) & 0x7E;
486
487 f = packFloatx80(0, 0x3FFF, fSig);
488 fp0 = packFloatx80(0, 0x3FFF, aSig);
489
490 fp0 = floatx80_sub(fp0, f, status);
491
492
493 fp0 = floatx80_mul(fp0, log_tbl[j], status);
494 logof2 = packFloatx80(0, 0x3FFE, UINT64_C(0xB17217F7D1CF79AC));
495 klog2 = floatx80_mul(fp1, logof2, status);
496 fp2 = floatx80_mul(fp0, fp0, status);
497
498 fp3 = fp2;
499 fp1 = fp2;
500
501 fp1 = floatx80_mul(fp1, float64_to_floatx80(
502 make_float64(0x3FC2499AB5E4040B), status),
503 status);
504 fp2 = floatx80_mul(fp2, float64_to_floatx80(
505 make_float64(0xBFC555B5848CB7DB), status),
506 status);
507 fp1 = floatx80_add(fp1, float64_to_floatx80(
508 make_float64(0x3FC99999987D8730), status),
509 status);
510 fp2 = floatx80_add(fp2, float64_to_floatx80(
511 make_float64(0xBFCFFFFFFF6F7E97), status),
512 status);
513 fp1 = floatx80_mul(fp1, fp3, status);
514 fp2 = floatx80_mul(fp2, fp3, status);
515 fp1 = floatx80_add(fp1, float64_to_floatx80(
516 make_float64(0x3FD55555555555A4), status),
517 status);
518 fp2 = floatx80_add(fp2, float64_to_floatx80(
519 make_float64(0xBFE0000000000008), status),
520 status);
521 fp1 = floatx80_mul(fp1, fp3, status);
522 fp2 = floatx80_mul(fp2, fp3, status);
523 fp1 = floatx80_mul(fp1, fp0, status);
524 fp0 = floatx80_add(fp0, fp2, status);
525
526 fp1 = floatx80_add(fp1, log_tbl[j + 1],
527 status);
528 fp0 = floatx80_add(fp0, fp1, status);
529
530 status->float_rounding_mode = user_rnd_mode;
531 status->floatx80_rounding_precision = user_rnd_prec;
532
533 a = floatx80_add(fp0, klog2, status);
534
535 float_raise(float_flag_inexact, status);
536
537 return a;
538 } else {
539 fp0 = a;
540 fp1 = a;
541 fp1 = floatx80_sub(fp1, float32_to_floatx80(make_float32(0x3F800000),
542 status), status);
543 fp0 = floatx80_add(fp0, float32_to_floatx80(make_float32(0x3F800000),
544 status), status);
545 fp1 = floatx80_add(fp1, fp1, status);
546
547
548 fp1 = floatx80_div(fp1, fp0, status);
549 saveu = fp1;
550 fp0 = floatx80_mul(fp1, fp1, status);
551 fp1 = floatx80_mul(fp0, fp0, status);
552
553 fp3 = float64_to_floatx80(make_float64(0x3F175496ADD7DAD6),
554 status);
555 fp2 = float64_to_floatx80(make_float64(0x3F3C71C2FE80C7E0),
556 status);
557 fp3 = floatx80_mul(fp3, fp1, status);
558 fp2 = floatx80_mul(fp2, fp1, status);
559 fp3 = floatx80_add(fp3, float64_to_floatx80(
560 make_float64(0x3F624924928BCCFF), status),
561 status);
562 fp2 = floatx80_add(fp2, float64_to_floatx80(
563 make_float64(0x3F899999999995EC), status),
564 status);
565 fp1 = floatx80_mul(fp1, fp3, status);
566 fp2 = floatx80_mul(fp2, fp0, status);
567 fp1 = floatx80_add(fp1, float64_to_floatx80(
568 make_float64(0x3FB5555555555555), status),
569 status);
570
571 fp0 = floatx80_mul(fp0, saveu, status);
572 fp1 = floatx80_add(fp1, fp2, status);
573 fp0 = floatx80_mul(fp0, fp1,
574 status);
575
576 status->float_rounding_mode = user_rnd_mode;
577 status->floatx80_rounding_precision = user_rnd_prec;
578
579 a = floatx80_add(fp0, saveu, status);
580
581
582 float_raise(float_flag_inexact, status);
583
584
585 return a;
586 }
587}
588
589
590
591
592
593floatx80 floatx80_log10(floatx80 a, float_status *status)
594{
595 bool aSign;
596 int32_t aExp;
597 uint64_t aSig;
598
599 FloatRoundMode user_rnd_mode;
600 FloatX80RoundPrec user_rnd_prec;
601
602 floatx80 fp0, fp1;
603
604 aSig = extractFloatx80Frac(a);
605 aExp = extractFloatx80Exp(a);
606 aSign = extractFloatx80Sign(a);
607
608 if (aExp == 0x7FFF) {
609 if ((uint64_t) (aSig << 1)) {
610 propagateFloatx80NaNOneArg(a, status);
611 }
612 if (aSign == 0) {
613 return packFloatx80(0, floatx80_infinity.high,
614 floatx80_infinity.low);
615 }
616 }
617
618 if (aExp == 0 && aSig == 0) {
619 float_raise(float_flag_divbyzero, status);
620 return packFloatx80(1, floatx80_infinity.high,
621 floatx80_infinity.low);
622 }
623
624 if (aSign) {
625 float_raise(float_flag_invalid, status);
626 return floatx80_default_nan(status);
627 }
628
629 user_rnd_mode = status->float_rounding_mode;
630 user_rnd_prec = status->floatx80_rounding_precision;
631 status->float_rounding_mode = float_round_nearest_even;
632 status->floatx80_rounding_precision = floatx80_precision_x;
633
634 fp0 = floatx80_logn(a, status);
635 fp1 = packFloatx80(0, 0x3FFD, UINT64_C(0xDE5BD8A937287195));
636
637 status->float_rounding_mode = user_rnd_mode;
638 status->floatx80_rounding_precision = user_rnd_prec;
639
640 a = floatx80_mul(fp0, fp1, status);
641
642 float_raise(float_flag_inexact, status);
643
644 return a;
645}
646
647
648
649
650
651floatx80 floatx80_log2(floatx80 a, float_status *status)
652{
653 bool aSign;
654 int32_t aExp;
655 uint64_t aSig;
656
657 FloatRoundMode user_rnd_mode;
658 FloatX80RoundPrec user_rnd_prec;
659
660 floatx80 fp0, fp1;
661
662 aSig = extractFloatx80Frac(a);
663 aExp = extractFloatx80Exp(a);
664 aSign = extractFloatx80Sign(a);
665
666 if (aExp == 0x7FFF) {
667 if ((uint64_t) (aSig << 1)) {
668 propagateFloatx80NaNOneArg(a, status);
669 }
670 if (aSign == 0) {
671 return packFloatx80(0, floatx80_infinity.high,
672 floatx80_infinity.low);
673 }
674 }
675
676 if (aExp == 0) {
677 if (aSig == 0) {
678 float_raise(float_flag_divbyzero, status);
679 return packFloatx80(1, floatx80_infinity.high,
680 floatx80_infinity.low);
681 }
682 normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
683 }
684
685 if (aSign) {
686 float_raise(float_flag_invalid, status);
687 return floatx80_default_nan(status);
688 }
689
690 user_rnd_mode = status->float_rounding_mode;
691 user_rnd_prec = status->floatx80_rounding_precision;
692 status->float_rounding_mode = float_round_nearest_even;
693 status->floatx80_rounding_precision = floatx80_precision_x;
694
695 if (aSig == one_sig) {
696 status->float_rounding_mode = user_rnd_mode;
697 status->floatx80_rounding_precision = user_rnd_prec;
698
699 a = int32_to_floatx80(aExp - 0x3FFF, status);
700 } else {
701 fp0 = floatx80_logn(a, status);
702 fp1 = packFloatx80(0, 0x3FFF, UINT64_C(0xB8AA3B295C17F0BC));
703
704 status->float_rounding_mode = user_rnd_mode;
705 status->floatx80_rounding_precision = user_rnd_prec;
706
707 a = floatx80_mul(fp0, fp1, status);
708 }
709
710 float_raise(float_flag_inexact, status);
711
712 return a;
713}
714
715
716
717
718
719floatx80 floatx80_etox(floatx80 a, float_status *status)
720{
721 bool aSign;
722 int32_t aExp;
723 uint64_t aSig;
724
725 FloatRoundMode user_rnd_mode;
726 FloatX80RoundPrec user_rnd_prec;
727
728 int32_t compact, n, j, k, m, m1;
729 floatx80 fp0, fp1, fp2, fp3, l2, scale, adjscale;
730 bool adjflag;
731
732 aSig = extractFloatx80Frac(a);
733 aExp = extractFloatx80Exp(a);
734 aSign = extractFloatx80Sign(a);
735
736 if (aExp == 0x7FFF) {
737 if ((uint64_t) (aSig << 1)) {
738 return propagateFloatx80NaNOneArg(a, status);
739 }
740 if (aSign) {
741 return packFloatx80(0, 0, 0);
742 }
743 return packFloatx80(0, floatx80_infinity.high,
744 floatx80_infinity.low);
745 }
746
747 if (aExp == 0 && aSig == 0) {
748 return packFloatx80(0, one_exp, one_sig);
749 }
750
751 user_rnd_mode = status->float_rounding_mode;
752 user_rnd_prec = status->floatx80_rounding_precision;
753 status->float_rounding_mode = float_round_nearest_even;
754 status->floatx80_rounding_precision = floatx80_precision_x;
755
756 adjflag = 0;
757
758 if (aExp >= 0x3FBE) {
759 compact = floatx80_make_compact(aExp, aSig);
760
761 if (compact < 0x400CB167) {
762 fp0 = a;
763 fp1 = a;
764 fp0 = floatx80_mul(fp0, float32_to_floatx80(
765 make_float32(0x42B8AA3B), status),
766 status);
767 adjflag = 0;
768 n = floatx80_to_int32(fp0, status);
769 fp0 = int32_to_floatx80(n, status);
770
771 j = n & 0x3F;
772 m = n / 64;
773 if (n < 0 && j) {
774
775
776
777
778 m--;
779 }
780 m += 0x3FFF;
781
782 expcont1:
783 fp2 = fp0;
784 fp0 = floatx80_mul(fp0, float32_to_floatx80(
785 make_float32(0xBC317218), status),
786 status);
787 l2 = packFloatx80(0, 0x3FDC, UINT64_C(0x82E308654361C4C6));
788 fp2 = floatx80_mul(fp2, l2, status);
789 fp0 = floatx80_add(fp0, fp1, status);
790 fp0 = floatx80_add(fp0, fp2, status);
791
792 fp1 = floatx80_mul(fp0, fp0, status);
793 fp2 = float32_to_floatx80(make_float32(0x3AB60B70),
794 status);
795 fp2 = floatx80_mul(fp2, fp1, status);
796 fp3 = floatx80_mul(float32_to_floatx80(make_float32(0x3C088895),
797 status), fp1,
798 status);
799 fp2 = floatx80_add(fp2, float64_to_floatx80(make_float64(
800 0x3FA5555555554431), status),
801 status);
802 fp3 = floatx80_add(fp3, float64_to_floatx80(make_float64(
803 0x3FC5555555554018), status),
804 status);
805 fp2 = floatx80_mul(fp2, fp1, status);
806 fp3 = floatx80_mul(fp3, fp1, status);
807 fp2 = floatx80_add(fp2, float32_to_floatx80(
808 make_float32(0x3F000000), status),
809 status);
810 fp3 = floatx80_mul(fp3, fp0, status);
811 fp2 = floatx80_mul(fp2, fp1,
812 status);
813 fp0 = floatx80_add(fp0, fp3, status);
814 fp0 = floatx80_add(fp0, fp2, status);
815
816 fp1 = exp_tbl[j];
817 fp0 = floatx80_mul(fp0, fp1, status);
818 fp0 = floatx80_add(fp0, float32_to_floatx80(exp_tbl2[j], status),
819 status);
820 fp0 = floatx80_add(fp0, fp1,
821 status);
822
823 scale = packFloatx80(0, m, one_sig);
824 if (adjflag) {
825 adjscale = packFloatx80(0, m1, one_sig);
826 fp0 = floatx80_mul(fp0, adjscale, status);
827 }
828
829 status->float_rounding_mode = user_rnd_mode;
830 status->floatx80_rounding_precision = user_rnd_prec;
831
832 a = floatx80_mul(fp0, scale, status);
833
834 float_raise(float_flag_inexact, status);
835
836 return a;
837 } else {
838 if (compact > 0x400CB27C) {
839 status->float_rounding_mode = user_rnd_mode;
840 status->floatx80_rounding_precision = user_rnd_prec;
841 if (aSign) {
842 a = roundAndPackFloatx80(
843 status->floatx80_rounding_precision,
844 0, -0x1000, aSig, 0, status);
845 } else {
846 a = roundAndPackFloatx80(
847 status->floatx80_rounding_precision,
848 0, 0x8000, aSig, 0, status);
849 }
850 float_raise(float_flag_inexact, status);
851
852 return a;
853 } else {
854 fp0 = a;
855 fp1 = a;
856 fp0 = floatx80_mul(fp0, float32_to_floatx80(
857 make_float32(0x42B8AA3B), status),
858 status);
859 adjflag = 1;
860 n = floatx80_to_int32(fp0, status);
861 fp0 = int32_to_floatx80(n, status);
862
863 j = n & 0x3F;
864
865 k = n / 64;
866 if (n < 0 && j) {
867
868
869
870 k--;
871 }
872
873 m1 = k / 2;
874 if (k < 0 && (k & 1)) {
875
876
877
878 m1--;
879 }
880 m = k - m1;
881 m1 += 0x3FFF;
882 m += 0x3FFF;
883
884 goto expcont1;
885 }
886 }
887 } else {
888 status->float_rounding_mode = user_rnd_mode;
889 status->floatx80_rounding_precision = user_rnd_prec;
890
891 a = floatx80_add(a, float32_to_floatx80(make_float32(0x3F800000),
892 status), status);
893
894 float_raise(float_flag_inexact, status);
895
896 return a;
897 }
898}
899
900
901
902
903
904floatx80 floatx80_twotox(floatx80 a, float_status *status)
905{
906 bool aSign;
907 int32_t aExp;
908 uint64_t aSig;
909
910 FloatRoundMode user_rnd_mode;
911 FloatX80RoundPrec user_rnd_prec;
912
913 int32_t compact, n, j, l, m, m1;
914 floatx80 fp0, fp1, fp2, fp3, adjfact, fact1, fact2;
915
916 aSig = extractFloatx80Frac(a);
917 aExp = extractFloatx80Exp(a);
918 aSign = extractFloatx80Sign(a);
919
920 if (aExp == 0x7FFF) {
921 if ((uint64_t) (aSig << 1)) {
922 return propagateFloatx80NaNOneArg(a, status);
923 }
924 if (aSign) {
925 return packFloatx80(0, 0, 0);
926 }
927 return packFloatx80(0, floatx80_infinity.high,
928 floatx80_infinity.low);
929 }
930
931 if (aExp == 0 && aSig == 0) {
932 return packFloatx80(0, one_exp, one_sig);
933 }
934
935 user_rnd_mode = status->float_rounding_mode;
936 user_rnd_prec = status->floatx80_rounding_precision;
937 status->float_rounding_mode = float_round_nearest_even;
938 status->floatx80_rounding_precision = floatx80_precision_x;
939
940 fp0 = a;
941
942 compact = floatx80_make_compact(aExp, aSig);
943
944 if (compact < 0x3FB98000 || compact > 0x400D80C0) {
945
946 if (compact > 0x3FFF8000) {
947 status->float_rounding_mode = user_rnd_mode;
948 status->floatx80_rounding_precision = user_rnd_prec;
949
950 if (aSign) {
951 return roundAndPackFloatx80(status->floatx80_rounding_precision,
952 0, -0x1000, aSig, 0, status);
953 } else {
954 return roundAndPackFloatx80(status->floatx80_rounding_precision,
955 0, 0x8000, aSig, 0, status);
956 }
957 } else {
958 status->float_rounding_mode = user_rnd_mode;
959 status->floatx80_rounding_precision = user_rnd_prec;
960
961 a = floatx80_add(fp0, float32_to_floatx80(
962 make_float32(0x3F800000), status),
963 status);
964
965 float_raise(float_flag_inexact, status);
966
967 return a;
968 }
969 } else {
970 fp1 = fp0;
971 fp1 = floatx80_mul(fp1, float32_to_floatx80(
972 make_float32(0x42800000), status),
973 status);
974 n = floatx80_to_int32(fp1, status);
975 fp1 = int32_to_floatx80(n, status);
976 j = n & 0x3F;
977 l = n / 64;
978 if (n < 0 && j) {
979
980
981
982
983 l--;
984 }
985 m = l / 2;
986 if (l < 0 && (l & 1)) {
987
988
989
990
991 m--;
992 }
993 m1 = l - m;
994 m1 += 0x3FFF;
995
996 adjfact = packFloatx80(0, m1, one_sig);
997 fact1 = exp2_tbl[j];
998 fact1.high += m;
999 fact2.high = exp2_tbl2[j] >> 16;
1000 fact2.high += m;
1001 fact2.low = (uint64_t)(exp2_tbl2[j] & 0xFFFF);
1002 fact2.low <<= 48;
1003
1004 fp1 = floatx80_mul(fp1, float32_to_floatx80(
1005 make_float32(0x3C800000), status),
1006 status);
1007 fp0 = floatx80_sub(fp0, fp1, status);
1008 fp2 = packFloatx80(0, 0x3FFE, UINT64_C(0xB17217F7D1CF79AC));
1009 fp0 = floatx80_mul(fp0, fp2, status);
1010
1011
1012 fp1 = floatx80_mul(fp0, fp0, status);
1013 fp2 = float64_to_floatx80(make_float64(0x3F56C16D6F7BD0B2),
1014 status);
1015 fp3 = float64_to_floatx80(make_float64(0x3F811112302C712C),
1016 status);
1017 fp2 = floatx80_mul(fp2, fp1, status);
1018 fp3 = floatx80_mul(fp3, fp1, status);
1019 fp2 = floatx80_add(fp2, float64_to_floatx80(
1020 make_float64(0x3FA5555555554CC1), status),
1021 status);
1022 fp3 = floatx80_add(fp3, float64_to_floatx80(
1023 make_float64(0x3FC5555555554A54), status),
1024 status);
1025 fp2 = floatx80_mul(fp2, fp1, status);
1026 fp3 = floatx80_mul(fp3, fp1, status);
1027 fp2 = floatx80_add(fp2, float64_to_floatx80(
1028 make_float64(0x3FE0000000000000), status),
1029 status);
1030 fp3 = floatx80_mul(fp3, fp0, status);
1031
1032 fp2 = floatx80_mul(fp2, fp1, status);
1033 fp0 = floatx80_add(fp0, fp3, status);
1034 fp0 = floatx80_add(fp0, fp2, status);
1035
1036 fp0 = floatx80_mul(fp0, fact1, status);
1037 fp0 = floatx80_add(fp0, fact2, status);
1038 fp0 = floatx80_add(fp0, fact1, status);
1039
1040 status->float_rounding_mode = user_rnd_mode;
1041 status->floatx80_rounding_precision = user_rnd_prec;
1042
1043 a = floatx80_mul(fp0, adjfact, status);
1044
1045 float_raise(float_flag_inexact, status);
1046
1047 return a;
1048 }
1049}
1050
1051
1052
1053
1054
1055floatx80 floatx80_tentox(floatx80 a, float_status *status)
1056{
1057 bool aSign;
1058 int32_t aExp;
1059 uint64_t aSig;
1060
1061 FloatRoundMode user_rnd_mode;
1062 FloatX80RoundPrec user_rnd_prec;
1063
1064 int32_t compact, n, j, l, m, m1;
1065 floatx80 fp0, fp1, fp2, fp3, adjfact, fact1, fact2;
1066
1067 aSig = extractFloatx80Frac(a);
1068 aExp = extractFloatx80Exp(a);
1069 aSign = extractFloatx80Sign(a);
1070
1071 if (aExp == 0x7FFF) {
1072 if ((uint64_t) (aSig << 1)) {
1073 return propagateFloatx80NaNOneArg(a, status);
1074 }
1075 if (aSign) {
1076 return packFloatx80(0, 0, 0);
1077 }
1078 return packFloatx80(0, floatx80_infinity.high,
1079 floatx80_infinity.low);
1080 }
1081
1082 if (aExp == 0 && aSig == 0) {
1083 return packFloatx80(0, one_exp, one_sig);
1084 }
1085
1086 user_rnd_mode = status->float_rounding_mode;
1087 user_rnd_prec = status->floatx80_rounding_precision;
1088 status->float_rounding_mode = float_round_nearest_even;
1089 status->floatx80_rounding_precision = floatx80_precision_x;
1090
1091 fp0 = a;
1092
1093 compact = floatx80_make_compact(aExp, aSig);
1094
1095 if (compact < 0x3FB98000 || compact > 0x400B9B07) {
1096
1097 if (compact > 0x3FFF8000) {
1098 status->float_rounding_mode = user_rnd_mode;
1099 status->floatx80_rounding_precision = user_rnd_prec;
1100
1101 if (aSign) {
1102 return roundAndPackFloatx80(status->floatx80_rounding_precision,
1103 0, -0x1000, aSig, 0, status);
1104 } else {
1105 return roundAndPackFloatx80(status->floatx80_rounding_precision,
1106 0, 0x8000, aSig, 0, status);
1107 }
1108 } else {
1109 status->float_rounding_mode = user_rnd_mode;
1110 status->floatx80_rounding_precision = user_rnd_prec;
1111
1112 a = floatx80_add(fp0, float32_to_floatx80(
1113 make_float32(0x3F800000), status),
1114 status);
1115
1116 float_raise(float_flag_inexact, status);
1117
1118 return a;
1119 }
1120 } else {
1121 fp1 = fp0;
1122 fp1 = floatx80_mul(fp1, float64_to_floatx80(
1123 make_float64(0x406A934F0979A371),
1124 status), status);
1125 n = floatx80_to_int32(fp1, status);
1126 fp1 = int32_to_floatx80(n, status);
1127
1128 j = n & 0x3F;
1129 l = n / 64;
1130 if (n < 0 && j) {
1131
1132
1133
1134
1135 l--;
1136 }
1137 m = l / 2;
1138 if (l < 0 && (l & 1)) {
1139
1140
1141
1142
1143 m--;
1144 }
1145 m1 = l - m;
1146 m1 += 0x3FFF;
1147
1148 adjfact = packFloatx80(0, m1, one_sig);
1149 fact1 = exp2_tbl[j];
1150 fact1.high += m;
1151 fact2.high = exp2_tbl2[j] >> 16;
1152 fact2.high += m;
1153 fact2.low = (uint64_t)(exp2_tbl2[j] & 0xFFFF);
1154 fact2.low <<= 48;
1155
1156 fp2 = fp1;
1157 fp1 = floatx80_mul(fp1, float64_to_floatx80(
1158 make_float64(0x3F734413509F8000), status),
1159 status);
1160 fp3 = packFloatx80(1, 0x3FCD, UINT64_C(0xC0219DC1DA994FD2));
1161 fp2 = floatx80_mul(fp2, fp3, status);
1162 fp0 = floatx80_sub(fp0, fp1, status);
1163 fp0 = floatx80_sub(fp0, fp2, status);
1164 fp2 = packFloatx80(0, 0x4000, UINT64_C(0x935D8DDDAAA8AC17));
1165 fp0 = floatx80_mul(fp0, fp2, status);
1166
1167
1168 fp1 = floatx80_mul(fp0, fp0, status);
1169 fp2 = float64_to_floatx80(make_float64(0x3F56C16D6F7BD0B2),
1170 status);
1171 fp3 = float64_to_floatx80(make_float64(0x3F811112302C712C),
1172 status);
1173 fp2 = floatx80_mul(fp2, fp1, status);
1174 fp3 = floatx80_mul(fp3, fp1, status);
1175 fp2 = floatx80_add(fp2, float64_to_floatx80(
1176 make_float64(0x3FA5555555554CC1), status),
1177 status);
1178 fp3 = floatx80_add(fp3, float64_to_floatx80(
1179 make_float64(0x3FC5555555554A54), status),
1180 status);
1181 fp2 = floatx80_mul(fp2, fp1, status);
1182 fp3 = floatx80_mul(fp3, fp1, status);
1183 fp2 = floatx80_add(fp2, float64_to_floatx80(
1184 make_float64(0x3FE0000000000000), status),
1185 status);
1186 fp3 = floatx80_mul(fp3, fp0, status);
1187
1188 fp2 = floatx80_mul(fp2, fp1, status);
1189 fp0 = floatx80_add(fp0, fp3, status);
1190 fp0 = floatx80_add(fp0, fp2, status);
1191
1192 fp0 = floatx80_mul(fp0, fact1, status);
1193 fp0 = floatx80_add(fp0, fact2, status);
1194 fp0 = floatx80_add(fp0, fact1, status);
1195
1196 status->float_rounding_mode = user_rnd_mode;
1197 status->floatx80_rounding_precision = user_rnd_prec;
1198
1199 a = floatx80_mul(fp0, adjfact, status);
1200
1201 float_raise(float_flag_inexact, status);
1202
1203 return a;
1204 }
1205}
1206
1207
1208
1209
1210
1211floatx80 floatx80_tan(floatx80 a, float_status *status)
1212{
1213 bool aSign, xSign;
1214 int32_t aExp, xExp;
1215 uint64_t aSig, xSig;
1216
1217 FloatRoundMode user_rnd_mode;
1218 FloatX80RoundPrec user_rnd_prec;
1219
1220 int32_t compact, l, n, j;
1221 floatx80 fp0, fp1, fp2, fp3, fp4, fp5, invtwopi, twopi1, twopi2;
1222 float32 twoto63;
1223 bool endflag;
1224
1225 aSig = extractFloatx80Frac(a);
1226 aExp = extractFloatx80Exp(a);
1227 aSign = extractFloatx80Sign(a);
1228
1229 if (aExp == 0x7FFF) {
1230 if ((uint64_t) (aSig << 1)) {
1231 return propagateFloatx80NaNOneArg(a, status);
1232 }
1233 float_raise(float_flag_invalid, status);
1234 return floatx80_default_nan(status);
1235 }
1236
1237 if (aExp == 0 && aSig == 0) {
1238 return packFloatx80(aSign, 0, 0);
1239 }
1240
1241 user_rnd_mode = status->float_rounding_mode;
1242 user_rnd_prec = status->floatx80_rounding_precision;
1243 status->float_rounding_mode = float_round_nearest_even;
1244 status->floatx80_rounding_precision = floatx80_precision_x;
1245
1246 compact = floatx80_make_compact(aExp, aSig);
1247
1248 fp0 = a;
1249
1250 if (compact < 0x3FD78000 || compact > 0x4004BC7E) {
1251
1252 if (compact > 0x3FFF8000) {
1253
1254 fp1 = packFloatx80(0, 0, 0);
1255 if (compact == 0x7FFEFFFF) {
1256 twopi1 = packFloatx80(aSign ^ 1, 0x7FFE,
1257 UINT64_C(0xC90FDAA200000000));
1258 twopi2 = packFloatx80(aSign ^ 1, 0x7FDC,
1259 UINT64_C(0x85A308D300000000));
1260 fp0 = floatx80_add(fp0, twopi1, status);
1261 fp1 = fp0;
1262 fp0 = floatx80_add(fp0, twopi2, status);
1263 fp1 = floatx80_sub(fp1, fp0, status);
1264 fp1 = floatx80_add(fp1, twopi2, status);
1265 }
1266 loop:
1267 xSign = extractFloatx80Sign(fp0);
1268 xExp = extractFloatx80Exp(fp0);
1269 xExp -= 0x3FFF;
1270 if (xExp <= 28) {
1271 l = 0;
1272 endflag = true;
1273 } else {
1274 l = xExp - 27;
1275 endflag = false;
1276 }
1277 invtwopi = packFloatx80(0, 0x3FFE - l,
1278 UINT64_C(0xA2F9836E4E44152A));
1279 twopi1 = packFloatx80(0, 0x3FFF + l, UINT64_C(0xC90FDAA200000000));
1280 twopi2 = packFloatx80(0, 0x3FDD + l, UINT64_C(0x85A308D300000000));
1281
1282
1283 twoto63 = packFloat32(xSign, 0xBE, 0);
1284
1285 fp2 = floatx80_mul(fp0, invtwopi, status);
1286 fp2 = floatx80_add(fp2, float32_to_floatx80(twoto63, status),
1287 status);
1288 fp2 = floatx80_sub(fp2, float32_to_floatx80(twoto63, status),
1289 status);
1290 fp4 = floatx80_mul(twopi1, fp2, status);
1291 fp5 = floatx80_mul(twopi2, fp2, status);
1292 fp3 = floatx80_add(fp4, fp5, status);
1293 fp4 = floatx80_sub(fp4, fp3, status);
1294 fp0 = floatx80_sub(fp0, fp3, status);
1295 fp4 = floatx80_add(fp4, fp5, status);
1296 fp3 = fp0;
1297 fp1 = floatx80_sub(fp1, fp4, status);
1298 fp0 = floatx80_add(fp0, fp1, status);
1299
1300 if (endflag) {
1301 n = floatx80_to_int32(fp2, status);
1302 goto tancont;
1303 }
1304 fp3 = floatx80_sub(fp3, fp0, status);
1305 fp1 = floatx80_add(fp1, fp3, status);
1306 goto loop;
1307 } else {
1308 status->float_rounding_mode = user_rnd_mode;
1309 status->floatx80_rounding_precision = user_rnd_prec;
1310
1311 a = floatx80_move(a, status);
1312
1313 float_raise(float_flag_inexact, status);
1314
1315 return a;
1316 }
1317 } else {
1318 fp1 = floatx80_mul(fp0, float64_to_floatx80(
1319 make_float64(0x3FE45F306DC9C883), status),
1320 status);
1321
1322 n = floatx80_to_int32(fp1, status);
1323 j = 32 + n;
1324
1325 fp0 = floatx80_sub(fp0, pi_tbl[j], status);
1326 fp0 = floatx80_sub(fp0, float32_to_floatx80(pi_tbl2[j], status),
1327 status);
1328
1329 tancont:
1330 if (n & 1) {
1331
1332 fp1 = fp0;
1333 fp0 = floatx80_mul(fp0, fp0, status);
1334 fp3 = float64_to_floatx80(make_float64(0x3EA0B759F50F8688),
1335 status);
1336 fp2 = float64_to_floatx80(make_float64(0xBEF2BAA5A8924F04),
1337 status);
1338 fp3 = floatx80_mul(fp3, fp0, status);
1339 fp2 = floatx80_mul(fp2, fp0, status);
1340 fp3 = floatx80_add(fp3, float64_to_floatx80(
1341 make_float64(0xBF346F59B39BA65F), status),
1342 status);
1343 fp4 = packFloatx80(0, 0x3FF6, UINT64_C(0xE073D3FC199C4A00));
1344 fp2 = floatx80_add(fp2, fp4, status);
1345 fp3 = floatx80_mul(fp3, fp0, status);
1346 fp2 = floatx80_mul(fp2, fp0, status);
1347 fp4 = packFloatx80(0, 0x3FF9, UINT64_C(0xD23CD68415D95FA1));
1348 fp3 = floatx80_add(fp3, fp4, status);
1349 fp4 = packFloatx80(1, 0x3FFC, UINT64_C(0x8895A6C5FB423BCA));
1350 fp2 = floatx80_add(fp2, fp4, status);
1351 fp3 = floatx80_mul(fp3, fp0, status);
1352 fp2 = floatx80_mul(fp2, fp0, status);
1353 fp4 = packFloatx80(1, 0x3FFD, UINT64_C(0xEEF57E0DA84BC8CE));
1354 fp3 = floatx80_add(fp3, fp4, status);
1355 fp2 = floatx80_mul(fp2, fp1, status);
1356 fp0 = floatx80_mul(fp0, fp3, status);
1357 fp1 = floatx80_add(fp1, fp2, status);
1358 fp0 = floatx80_add(fp0, float32_to_floatx80(
1359 make_float32(0x3F800000), status),
1360 status);
1361
1362 xSign = extractFloatx80Sign(fp1);
1363 xExp = extractFloatx80Exp(fp1);
1364 xSig = extractFloatx80Frac(fp1);
1365 xSign ^= 1;
1366 fp1 = packFloatx80(xSign, xExp, xSig);
1367
1368 status->float_rounding_mode = user_rnd_mode;
1369 status->floatx80_rounding_precision = user_rnd_prec;
1370
1371 a = floatx80_div(fp0, fp1, status);
1372
1373 float_raise(float_flag_inexact, status);
1374
1375 return a;
1376 } else {
1377 fp1 = floatx80_mul(fp0, fp0, status);
1378 fp3 = float64_to_floatx80(make_float64(0x3EA0B759F50F8688),
1379 status);
1380 fp2 = float64_to_floatx80(make_float64(0xBEF2BAA5A8924F04),
1381 status);
1382 fp3 = floatx80_mul(fp3, fp1, status);
1383 fp2 = floatx80_mul(fp2, fp1, status);
1384 fp3 = floatx80_add(fp3, float64_to_floatx80(
1385 make_float64(0xBF346F59B39BA65F), status),
1386 status);
1387 fp4 = packFloatx80(0, 0x3FF6, UINT64_C(0xE073D3FC199C4A00));
1388 fp2 = floatx80_add(fp2, fp4, status);
1389 fp3 = floatx80_mul(fp3, fp1, status);
1390 fp2 = floatx80_mul(fp2, fp1, status);
1391 fp4 = packFloatx80(0, 0x3FF9, UINT64_C(0xD23CD68415D95FA1));
1392 fp3 = floatx80_add(fp3, fp4, status);
1393 fp4 = packFloatx80(1, 0x3FFC, UINT64_C(0x8895A6C5FB423BCA));
1394 fp2 = floatx80_add(fp2, fp4, status);
1395 fp3 = floatx80_mul(fp3, fp1, status);
1396 fp2 = floatx80_mul(fp2, fp1, status);
1397 fp4 = packFloatx80(1, 0x3FFD, UINT64_C(0xEEF57E0DA84BC8CE));
1398 fp3 = floatx80_add(fp3, fp4, status);
1399 fp2 = floatx80_mul(fp2, fp0, status);
1400 fp1 = floatx80_mul(fp1, fp3, status);
1401 fp0 = floatx80_add(fp0, fp2, status);
1402 fp1 = floatx80_add(fp1, float32_to_floatx80(
1403 make_float32(0x3F800000), status),
1404 status);
1405
1406 status->float_rounding_mode = user_rnd_mode;
1407 status->floatx80_rounding_precision = user_rnd_prec;
1408
1409 a = floatx80_div(fp0, fp1, status);
1410
1411 float_raise(float_flag_inexact, status);
1412
1413 return a;
1414 }
1415 }
1416}
1417
1418
1419
1420
1421
1422floatx80 floatx80_sin(floatx80 a, float_status *status)
1423{
1424 bool aSign, xSign;
1425 int32_t aExp, xExp;
1426 uint64_t aSig, xSig;
1427
1428 FloatRoundMode user_rnd_mode;
1429 FloatX80RoundPrec user_rnd_prec;
1430
1431 int32_t compact, l, n, j;
1432 floatx80 fp0, fp1, fp2, fp3, fp4, fp5, x, invtwopi, twopi1, twopi2;
1433 float32 posneg1, twoto63;
1434 bool endflag;
1435
1436 aSig = extractFloatx80Frac(a);
1437 aExp = extractFloatx80Exp(a);
1438 aSign = extractFloatx80Sign(a);
1439
1440 if (aExp == 0x7FFF) {
1441 if ((uint64_t) (aSig << 1)) {
1442 return propagateFloatx80NaNOneArg(a, status);
1443 }
1444 float_raise(float_flag_invalid, status);
1445 return floatx80_default_nan(status);
1446 }
1447
1448 if (aExp == 0 && aSig == 0) {
1449 return packFloatx80(aSign, 0, 0);
1450 }
1451
1452 user_rnd_mode = status->float_rounding_mode;
1453 user_rnd_prec = status->floatx80_rounding_precision;
1454 status->float_rounding_mode = float_round_nearest_even;
1455 status->floatx80_rounding_precision = floatx80_precision_x;
1456
1457 compact = floatx80_make_compact(aExp, aSig);
1458
1459 fp0 = a;
1460
1461 if (compact < 0x3FD78000 || compact > 0x4004BC7E) {
1462
1463 if (compact > 0x3FFF8000) {
1464
1465 fp1 = packFloatx80(0, 0, 0);
1466 if (compact == 0x7FFEFFFF) {
1467 twopi1 = packFloatx80(aSign ^ 1, 0x7FFE,
1468 UINT64_C(0xC90FDAA200000000));
1469 twopi2 = packFloatx80(aSign ^ 1, 0x7FDC,
1470 UINT64_C(0x85A308D300000000));
1471 fp0 = floatx80_add(fp0, twopi1, status);
1472 fp1 = fp0;
1473 fp0 = floatx80_add(fp0, twopi2, status);
1474 fp1 = floatx80_sub(fp1, fp0, status);
1475 fp1 = floatx80_add(fp1, twopi2, status);
1476 }
1477 loop:
1478 xSign = extractFloatx80Sign(fp0);
1479 xExp = extractFloatx80Exp(fp0);
1480 xExp -= 0x3FFF;
1481 if (xExp <= 28) {
1482 l = 0;
1483 endflag = true;
1484 } else {
1485 l = xExp - 27;
1486 endflag = false;
1487 }
1488 invtwopi = packFloatx80(0, 0x3FFE - l,
1489 UINT64_C(0xA2F9836E4E44152A));
1490 twopi1 = packFloatx80(0, 0x3FFF + l, UINT64_C(0xC90FDAA200000000));
1491 twopi2 = packFloatx80(0, 0x3FDD + l, UINT64_C(0x85A308D300000000));
1492
1493
1494 twoto63 = packFloat32(xSign, 0xBE, 0);
1495
1496 fp2 = floatx80_mul(fp0, invtwopi, status);
1497 fp2 = floatx80_add(fp2, float32_to_floatx80(twoto63, status),
1498 status);
1499 fp2 = floatx80_sub(fp2, float32_to_floatx80(twoto63, status),
1500 status);
1501 fp4 = floatx80_mul(twopi1, fp2, status);
1502 fp5 = floatx80_mul(twopi2, fp2, status);
1503 fp3 = floatx80_add(fp4, fp5, status);
1504 fp4 = floatx80_sub(fp4, fp3, status);
1505 fp0 = floatx80_sub(fp0, fp3, status);
1506 fp4 = floatx80_add(fp4, fp5, status);
1507 fp3 = fp0;
1508 fp1 = floatx80_sub(fp1, fp4, status);
1509 fp0 = floatx80_add(fp0, fp1, status);
1510
1511 if (endflag) {
1512 n = floatx80_to_int32(fp2, status);
1513 goto sincont;
1514 }
1515 fp3 = floatx80_sub(fp3, fp0, status);
1516 fp1 = floatx80_add(fp1, fp3, status);
1517 goto loop;
1518 } else {
1519
1520 fp0 = float32_to_floatx80(make_float32(0x3F800000),
1521 status);
1522
1523 status->float_rounding_mode = user_rnd_mode;
1524 status->floatx80_rounding_precision = user_rnd_prec;
1525
1526
1527 a = floatx80_move(a, status);
1528 float_raise(float_flag_inexact, status);
1529
1530 return a;
1531 }
1532 } else {
1533 fp1 = floatx80_mul(fp0, float64_to_floatx80(
1534 make_float64(0x3FE45F306DC9C883), status),
1535 status);
1536
1537 n = floatx80_to_int32(fp1, status);
1538 j = 32 + n;
1539
1540 fp0 = floatx80_sub(fp0, pi_tbl[j], status);
1541 fp0 = floatx80_sub(fp0, float32_to_floatx80(pi_tbl2[j], status),
1542 status);
1543
1544 sincont:
1545 if (n & 1) {
1546
1547 fp0 = floatx80_mul(fp0, fp0, status);
1548 fp1 = floatx80_mul(fp0, fp0, status);
1549 fp2 = float64_to_floatx80(make_float64(0x3D2AC4D0D6011EE3),
1550 status);
1551 fp3 = float64_to_floatx80(make_float64(0xBDA9396F9F45AC19),
1552 status);
1553
1554 xSign = extractFloatx80Sign(fp0);
1555 xExp = extractFloatx80Exp(fp0);
1556 xSig = extractFloatx80Frac(fp0);
1557
1558 if ((n >> 1) & 1) {
1559 xSign ^= 1;
1560 posneg1 = make_float32(0xBF800000);
1561 } else {
1562 xSign ^= 0;
1563 posneg1 = make_float32(0x3F800000);
1564 }
1565
1566 fp2 = floatx80_mul(fp2, fp1, status);
1567 fp3 = floatx80_mul(fp3, fp1, status);
1568 fp2 = floatx80_add(fp2, float64_to_floatx80(
1569 make_float64(0x3E21EED90612C972), status),
1570 status);
1571 fp3 = floatx80_add(fp3, float64_to_floatx80(
1572 make_float64(0xBE927E4FB79D9FCF), status),
1573 status);
1574 fp2 = floatx80_mul(fp2, fp1, status);
1575 fp3 = floatx80_mul(fp3, fp1, status);
1576 fp2 = floatx80_add(fp2, float64_to_floatx80(
1577 make_float64(0x3EFA01A01A01D423), status),
1578 status);
1579 fp4 = packFloatx80(1, 0x3FF5, UINT64_C(0xB60B60B60B61D438));
1580 fp3 = floatx80_add(fp3, fp4, status);
1581 fp2 = floatx80_mul(fp2, fp1, status);
1582 fp1 = floatx80_mul(fp1, fp3, status);
1583 fp4 = packFloatx80(0, 0x3FFA, UINT64_C(0xAAAAAAAAAAAAAB5E));
1584 fp2 = floatx80_add(fp2, fp4, status);
1585 fp1 = floatx80_add(fp1, float32_to_floatx80(
1586 make_float32(0xBF000000), status),
1587 status);
1588 fp0 = floatx80_mul(fp0, fp2, status);
1589 fp0 = floatx80_add(fp0, fp1, status);
1590
1591
1592
1593 x = packFloatx80(xSign, xExp, xSig);
1594 fp0 = floatx80_mul(fp0, x, status);
1595
1596 status->float_rounding_mode = user_rnd_mode;
1597 status->floatx80_rounding_precision = user_rnd_prec;
1598
1599 a = floatx80_add(fp0, float32_to_floatx80(posneg1, status), status);
1600
1601 float_raise(float_flag_inexact, status);
1602
1603 return a;
1604 } else {
1605
1606 xSign = extractFloatx80Sign(fp0);
1607 xExp = extractFloatx80Exp(fp0);
1608 xSig = extractFloatx80Frac(fp0);
1609
1610 xSign ^= (n >> 1) & 1;
1611
1612 fp0 = floatx80_mul(fp0, fp0, status);
1613 fp1 = floatx80_mul(fp0, fp0, status);
1614 fp3 = float64_to_floatx80(make_float64(0xBD6AAA77CCC994F5),
1615 status);
1616 fp2 = float64_to_floatx80(make_float64(0x3DE612097AAE8DA1),
1617 status);
1618 fp3 = floatx80_mul(fp3, fp1, status);
1619 fp2 = floatx80_mul(fp2, fp1, status);
1620 fp3 = floatx80_add(fp3, float64_to_floatx80(
1621 make_float64(0xBE5AE6452A118AE4), status),
1622 status);
1623 fp2 = floatx80_add(fp2, float64_to_floatx80(
1624 make_float64(0x3EC71DE3A5341531), status),
1625 status);
1626 fp3 = floatx80_mul(fp3, fp1, status);
1627 fp2 = floatx80_mul(fp2, fp1, status);
1628 fp3 = floatx80_add(fp3, float64_to_floatx80(
1629 make_float64(0xBF2A01A01A018B59), status),
1630 status);
1631 fp4 = packFloatx80(0, 0x3FF8, UINT64_C(0x88888888888859AF));
1632 fp2 = floatx80_add(fp2, fp4, status);
1633 fp1 = floatx80_mul(fp1, fp3, status);
1634 fp2 = floatx80_mul(fp2, fp0, status);
1635 fp4 = packFloatx80(1, 0x3FFC, UINT64_C(0xAAAAAAAAAAAAAA99));
1636 fp1 = floatx80_add(fp1, fp4, status);
1637 fp1 = floatx80_add(fp1, fp2,
1638 status);
1639
1640
1641
1642 x = packFloatx80(xSign, xExp, xSig);
1643 fp0 = floatx80_mul(fp0, x, status);
1644 fp0 = floatx80_mul(fp0, fp1, status);
1645
1646 status->float_rounding_mode = user_rnd_mode;
1647 status->floatx80_rounding_precision = user_rnd_prec;
1648
1649 a = floatx80_add(fp0, x, status);
1650
1651 float_raise(float_flag_inexact, status);
1652
1653 return a;
1654 }
1655 }
1656}
1657
1658
1659
1660
1661
1662floatx80 floatx80_cos(floatx80 a, float_status *status)
1663{
1664 bool aSign, xSign;
1665 int32_t aExp, xExp;
1666 uint64_t aSig, xSig;
1667
1668 FloatRoundMode user_rnd_mode;
1669 FloatX80RoundPrec user_rnd_prec;
1670
1671 int32_t compact, l, n, j;
1672 floatx80 fp0, fp1, fp2, fp3, fp4, fp5, x, invtwopi, twopi1, twopi2;
1673 float32 posneg1, twoto63;
1674 bool endflag;
1675
1676 aSig = extractFloatx80Frac(a);
1677 aExp = extractFloatx80Exp(a);
1678 aSign = extractFloatx80Sign(a);
1679
1680 if (aExp == 0x7FFF) {
1681 if ((uint64_t) (aSig << 1)) {
1682 return propagateFloatx80NaNOneArg(a, status);
1683 }
1684 float_raise(float_flag_invalid, status);
1685 return floatx80_default_nan(status);
1686 }
1687
1688 if (aExp == 0 && aSig == 0) {
1689 return packFloatx80(0, one_exp, one_sig);
1690 }
1691
1692 user_rnd_mode = status->float_rounding_mode;
1693 user_rnd_prec = status->floatx80_rounding_precision;
1694 status->float_rounding_mode = float_round_nearest_even;
1695 status->floatx80_rounding_precision = floatx80_precision_x;
1696
1697 compact = floatx80_make_compact(aExp, aSig);
1698
1699 fp0 = a;
1700
1701 if (compact < 0x3FD78000 || compact > 0x4004BC7E) {
1702
1703 if (compact > 0x3FFF8000) {
1704
1705 fp1 = packFloatx80(0, 0, 0);
1706 if (compact == 0x7FFEFFFF) {
1707 twopi1 = packFloatx80(aSign ^ 1, 0x7FFE,
1708 UINT64_C(0xC90FDAA200000000));
1709 twopi2 = packFloatx80(aSign ^ 1, 0x7FDC,
1710 UINT64_C(0x85A308D300000000));
1711 fp0 = floatx80_add(fp0, twopi1, status);
1712 fp1 = fp0;
1713 fp0 = floatx80_add(fp0, twopi2, status);
1714 fp1 = floatx80_sub(fp1, fp0, status);
1715 fp1 = floatx80_add(fp1, twopi2, status);
1716 }
1717 loop:
1718 xSign = extractFloatx80Sign(fp0);
1719 xExp = extractFloatx80Exp(fp0);
1720 xExp -= 0x3FFF;
1721 if (xExp <= 28) {
1722 l = 0;
1723 endflag = true;
1724 } else {
1725 l = xExp - 27;
1726 endflag = false;
1727 }
1728 invtwopi = packFloatx80(0, 0x3FFE - l,
1729 UINT64_C(0xA2F9836E4E44152A));
1730 twopi1 = packFloatx80(0, 0x3FFF + l, UINT64_C(0xC90FDAA200000000));
1731 twopi2 = packFloatx80(0, 0x3FDD + l, UINT64_C(0x85A308D300000000));
1732
1733
1734 twoto63 = packFloat32(xSign, 0xBE, 0);
1735
1736 fp2 = floatx80_mul(fp0, invtwopi, status);
1737 fp2 = floatx80_add(fp2, float32_to_floatx80(twoto63, status),
1738 status);
1739 fp2 = floatx80_sub(fp2, float32_to_floatx80(twoto63, status),
1740 status);
1741 fp4 = floatx80_mul(twopi1, fp2, status);
1742 fp5 = floatx80_mul(twopi2, fp2, status);
1743 fp3 = floatx80_add(fp4, fp5, status);
1744 fp4 = floatx80_sub(fp4, fp3, status);
1745 fp0 = floatx80_sub(fp0, fp3, status);
1746 fp4 = floatx80_add(fp4, fp5, status);
1747 fp3 = fp0;
1748 fp1 = floatx80_sub(fp1, fp4, status);
1749 fp0 = floatx80_add(fp0, fp1, status);
1750
1751 if (endflag) {
1752 n = floatx80_to_int32(fp2, status);
1753 goto sincont;
1754 }
1755 fp3 = floatx80_sub(fp3, fp0, status);
1756 fp1 = floatx80_add(fp1, fp3, status);
1757 goto loop;
1758 } else {
1759
1760 fp0 = float32_to_floatx80(make_float32(0x3F800000), status);
1761
1762 status->float_rounding_mode = user_rnd_mode;
1763 status->floatx80_rounding_precision = user_rnd_prec;
1764
1765
1766 a = floatx80_sub(fp0, float32_to_floatx80(
1767 make_float32(0x00800000), status),
1768 status);
1769 float_raise(float_flag_inexact, status);
1770
1771 return a;
1772 }
1773 } else {
1774 fp1 = floatx80_mul(fp0, float64_to_floatx80(
1775 make_float64(0x3FE45F306DC9C883), status),
1776 status);
1777
1778 n = floatx80_to_int32(fp1, status);
1779 j = 32 + n;
1780
1781 fp0 = floatx80_sub(fp0, pi_tbl[j], status);
1782 fp0 = floatx80_sub(fp0, float32_to_floatx80(pi_tbl2[j], status),
1783 status);
1784
1785 sincont:
1786 if ((n + 1) & 1) {
1787
1788 fp0 = floatx80_mul(fp0, fp0, status);
1789 fp1 = floatx80_mul(fp0, fp0, status);
1790 fp2 = float64_to_floatx80(make_float64(0x3D2AC4D0D6011EE3),
1791 status);
1792 fp3 = float64_to_floatx80(make_float64(0xBDA9396F9F45AC19),
1793 status);
1794
1795 xSign = extractFloatx80Sign(fp0);
1796 xExp = extractFloatx80Exp(fp0);
1797 xSig = extractFloatx80Frac(fp0);
1798
1799 if (((n + 1) >> 1) & 1) {
1800 xSign ^= 1;
1801 posneg1 = make_float32(0xBF800000);
1802 } else {
1803 xSign ^= 0;
1804 posneg1 = make_float32(0x3F800000);
1805 }
1806
1807 fp2 = floatx80_mul(fp2, fp1, status);
1808 fp3 = floatx80_mul(fp3, fp1, status);
1809 fp2 = floatx80_add(fp2, float64_to_floatx80(
1810 make_float64(0x3E21EED90612C972), status),
1811 status);
1812 fp3 = floatx80_add(fp3, float64_to_floatx80(
1813 make_float64(0xBE927E4FB79D9FCF), status),
1814 status);
1815 fp2 = floatx80_mul(fp2, fp1, status);
1816 fp3 = floatx80_mul(fp3, fp1, status);
1817 fp2 = floatx80_add(fp2, float64_to_floatx80(
1818 make_float64(0x3EFA01A01A01D423), status),
1819 status);
1820 fp4 = packFloatx80(1, 0x3FF5, UINT64_C(0xB60B60B60B61D438));
1821 fp3 = floatx80_add(fp3, fp4, status);
1822 fp2 = floatx80_mul(fp2, fp1, status);
1823 fp1 = floatx80_mul(fp1, fp3, status);
1824 fp4 = packFloatx80(0, 0x3FFA, UINT64_C(0xAAAAAAAAAAAAAB5E));
1825 fp2 = floatx80_add(fp2, fp4, status);
1826 fp1 = floatx80_add(fp1, float32_to_floatx80(
1827 make_float32(0xBF000000), status),
1828 status);
1829 fp0 = floatx80_mul(fp0, fp2, status);
1830 fp0 = floatx80_add(fp0, fp1, status);
1831
1832
1833 x = packFloatx80(xSign, xExp, xSig);
1834 fp0 = floatx80_mul(fp0, x, status);
1835
1836 status->float_rounding_mode = user_rnd_mode;
1837 status->floatx80_rounding_precision = user_rnd_prec;
1838
1839 a = floatx80_add(fp0, float32_to_floatx80(posneg1, status), status);
1840
1841 float_raise(float_flag_inexact, status);
1842
1843 return a;
1844 } else {
1845
1846 xSign = extractFloatx80Sign(fp0);
1847 xExp = extractFloatx80Exp(fp0);
1848 xSig = extractFloatx80Frac(fp0);
1849
1850 xSign ^= ((n + 1) >> 1) & 1;
1851
1852 fp0 = floatx80_mul(fp0, fp0, status);
1853 fp1 = floatx80_mul(fp0, fp0, status);
1854 fp3 = float64_to_floatx80(make_float64(0xBD6AAA77CCC994F5),
1855 status);
1856 fp2 = float64_to_floatx80(make_float64(0x3DE612097AAE8DA1),
1857 status);
1858 fp3 = floatx80_mul(fp3, fp1, status);
1859 fp2 = floatx80_mul(fp2, fp1, status);
1860 fp3 = floatx80_add(fp3, float64_to_floatx80(
1861 make_float64(0xBE5AE6452A118AE4), status),
1862 status);
1863 fp2 = floatx80_add(fp2, float64_to_floatx80(
1864 make_float64(0x3EC71DE3A5341531), status),
1865 status);
1866 fp3 = floatx80_mul(fp3, fp1, status);
1867 fp2 = floatx80_mul(fp2, fp1, status);
1868 fp3 = floatx80_add(fp3, float64_to_floatx80(
1869 make_float64(0xBF2A01A01A018B59), status),
1870 status);
1871 fp4 = packFloatx80(0, 0x3FF8, UINT64_C(0x88888888888859AF));
1872 fp2 = floatx80_add(fp2, fp4, status);
1873 fp1 = floatx80_mul(fp1, fp3, status);
1874 fp2 = floatx80_mul(fp2, fp0, status);
1875 fp4 = packFloatx80(1, 0x3FFC, UINT64_C(0xAAAAAAAAAAAAAA99));
1876 fp1 = floatx80_add(fp1, fp4, status);
1877 fp1 = floatx80_add(fp1, fp2, status);
1878
1879
1880 x = packFloatx80(xSign, xExp, xSig);
1881 fp0 = floatx80_mul(fp0, x, status);
1882 fp0 = floatx80_mul(fp0, fp1, status);
1883
1884 status->float_rounding_mode = user_rnd_mode;
1885 status->floatx80_rounding_precision = user_rnd_prec;
1886
1887 a = floatx80_add(fp0, x, status);
1888
1889 float_raise(float_flag_inexact, status);
1890
1891 return a;
1892 }
1893 }
1894}
1895
1896
1897
1898
1899
1900floatx80 floatx80_atan(floatx80 a, float_status *status)
1901{
1902 bool aSign;
1903 int32_t aExp;
1904 uint64_t aSig;
1905
1906 FloatRoundMode user_rnd_mode;
1907 FloatX80RoundPrec user_rnd_prec;
1908
1909 int32_t compact, tbl_index;
1910 floatx80 fp0, fp1, fp2, fp3, xsave;
1911
1912 aSig = extractFloatx80Frac(a);
1913 aExp = extractFloatx80Exp(a);
1914 aSign = extractFloatx80Sign(a);
1915
1916 if (aExp == 0x7FFF) {
1917 if ((uint64_t) (aSig << 1)) {
1918 return propagateFloatx80NaNOneArg(a, status);
1919 }
1920 a = packFloatx80(aSign, piby2_exp, pi_sig);
1921 float_raise(float_flag_inexact, status);
1922 return floatx80_move(a, status);
1923 }
1924
1925 if (aExp == 0 && aSig == 0) {
1926 return packFloatx80(aSign, 0, 0);
1927 }
1928
1929 compact = floatx80_make_compact(aExp, aSig);
1930
1931 user_rnd_mode = status->float_rounding_mode;
1932 user_rnd_prec = status->floatx80_rounding_precision;
1933 status->float_rounding_mode = float_round_nearest_even;
1934 status->floatx80_rounding_precision = floatx80_precision_x;
1935
1936 if (compact < 0x3FFB8000 || compact > 0x4002FFFF) {
1937
1938 if (compact > 0x3FFF8000) {
1939 if (compact > 0x40638000) {
1940 fp0 = packFloatx80(aSign, piby2_exp, pi_sig);
1941 fp1 = packFloatx80(aSign, 0x0001, one_sig);
1942
1943 status->float_rounding_mode = user_rnd_mode;
1944 status->floatx80_rounding_precision = user_rnd_prec;
1945
1946 a = floatx80_sub(fp0, fp1, status);
1947
1948 float_raise(float_flag_inexact, status);
1949
1950 return a;
1951 } else {
1952 fp0 = a;
1953 fp1 = packFloatx80(1, one_exp, one_sig);
1954 fp1 = floatx80_div(fp1, fp0, status);
1955 xsave = fp1;
1956 fp0 = floatx80_mul(fp1, fp1, status);
1957 fp1 = floatx80_mul(fp0, fp0, status);
1958 fp3 = float64_to_floatx80(make_float64(0xBFB70BF398539E6A),
1959 status);
1960 fp2 = float64_to_floatx80(make_float64(0x3FBC7187962D1D7D),
1961 status);
1962 fp3 = floatx80_mul(fp3, fp1, status);
1963 fp2 = floatx80_mul(fp2, fp1, status);
1964 fp3 = floatx80_add(fp3, float64_to_floatx80(
1965 make_float64(0xBFC24924827107B8), status),
1966 status);
1967 fp2 = floatx80_add(fp2, float64_to_floatx80(
1968 make_float64(0x3FC999999996263E), status),
1969 status);
1970 fp1 = floatx80_mul(fp1, fp3, status);
1971 fp2 = floatx80_mul(fp2, fp0, status);
1972 fp1 = floatx80_add(fp1, float64_to_floatx80(
1973 make_float64(0xBFD5555555555536), status),
1974 status);
1975 fp0 = floatx80_mul(fp0, xsave, status);
1976
1977 fp1 = floatx80_add(fp1, fp2, status);
1978
1979 fp0 = floatx80_mul(fp0, fp1, status);
1980 fp0 = floatx80_add(fp0, xsave, status);
1981 fp1 = packFloatx80(aSign, piby2_exp, pi_sig);
1982
1983 status->float_rounding_mode = user_rnd_mode;
1984 status->floatx80_rounding_precision = user_rnd_prec;
1985
1986 a = floatx80_add(fp0, fp1, status);
1987
1988 float_raise(float_flag_inexact, status);
1989
1990 return a;
1991 }
1992 } else {
1993 if (compact < 0x3FD78000) {
1994 status->float_rounding_mode = user_rnd_mode;
1995 status->floatx80_rounding_precision = user_rnd_prec;
1996
1997 a = floatx80_move(a, status);
1998
1999 float_raise(float_flag_inexact, status);
2000
2001 return a;
2002 } else {
2003 fp0 = a;
2004 xsave = a;
2005 fp0 = floatx80_mul(fp0, fp0, status);
2006 fp1 = floatx80_mul(fp0, fp0, status);
2007 fp2 = float64_to_floatx80(make_float64(0x3FB344447F876989),
2008 status);
2009 fp3 = float64_to_floatx80(make_float64(0xBFB744EE7FAF45DB),
2010 status);
2011 fp2 = floatx80_mul(fp2, fp1, status);
2012 fp3 = floatx80_mul(fp3, fp1, status);
2013 fp2 = floatx80_add(fp2, float64_to_floatx80(
2014 make_float64(0x3FBC71C646940220), status),
2015 status);
2016 fp3 = floatx80_add(fp3, float64_to_floatx80(
2017 make_float64(0xBFC24924921872F9),
2018 status), status);
2019 fp2 = floatx80_mul(fp2, fp1, status);
2020 fp1 = floatx80_mul(fp1, fp3, status);
2021 fp2 = floatx80_add(fp2, float64_to_floatx80(
2022 make_float64(0x3FC9999999998FA9), status),
2023 status);
2024 fp1 = floatx80_add(fp1, float64_to_floatx80(
2025 make_float64(0xBFD5555555555555), status),
2026 status);
2027 fp2 = floatx80_mul(fp2, fp0, status);
2028 fp0 = floatx80_mul(fp0, xsave, status);
2029
2030 fp1 = floatx80_add(fp1, fp2, status);
2031
2032 fp0 = floatx80_mul(fp0, fp1, status);
2033
2034 status->float_rounding_mode = user_rnd_mode;
2035 status->floatx80_rounding_precision = user_rnd_prec;
2036
2037 a = floatx80_add(fp0, xsave, status);
2038
2039 float_raise(float_flag_inexact, status);
2040
2041 return a;
2042 }
2043 }
2044 } else {
2045 aSig &= UINT64_C(0xF800000000000000);
2046 aSig |= UINT64_C(0x0400000000000000);
2047 xsave = packFloatx80(aSign, aExp, aSig);
2048 fp0 = a;
2049 fp1 = a;
2050 fp2 = packFloatx80(0, one_exp, one_sig);
2051 fp1 = floatx80_mul(fp1, xsave, status);
2052 fp0 = floatx80_sub(fp0, xsave, status);
2053 fp1 = floatx80_add(fp1, fp2, status);
2054 fp0 = floatx80_div(fp0, fp1, status);
2055
2056 tbl_index = compact;
2057
2058 tbl_index &= 0x7FFF0000;
2059 tbl_index -= 0x3FFB0000;
2060 tbl_index >>= 1;
2061 tbl_index += compact & 0x00007800;
2062 tbl_index >>= 11;
2063
2064 fp3 = atan_tbl[tbl_index];
2065
2066 fp3.high |= aSign ? 0x8000 : 0;
2067
2068 fp1 = floatx80_mul(fp0, fp0, status);
2069 fp2 = float64_to_floatx80(make_float64(0xBFF6687E314987D8),
2070 status);
2071 fp2 = floatx80_add(fp2, fp1, status);
2072 fp2 = floatx80_mul(fp2, fp1, status);
2073 fp1 = floatx80_mul(fp1, fp0, status);
2074 fp2 = floatx80_add(fp2, float64_to_floatx80(
2075 make_float64(0x4002AC6934A26DB3), status),
2076 status);
2077 fp1 = floatx80_mul(fp1, float64_to_floatx80(
2078 make_float64(0xBFC2476F4E1DA28E), status),
2079 status);
2080 fp1 = floatx80_mul(fp1, fp2, status);
2081 fp0 = floatx80_add(fp0, fp1, status);
2082
2083 status->float_rounding_mode = user_rnd_mode;
2084 status->floatx80_rounding_precision = user_rnd_prec;
2085
2086 a = floatx80_add(fp0, fp3, status);
2087
2088 float_raise(float_flag_inexact, status);
2089
2090 return a;
2091 }
2092}
2093
2094
2095
2096
2097
2098floatx80 floatx80_asin(floatx80 a, float_status *status)
2099{
2100 bool aSign;
2101 int32_t aExp;
2102 uint64_t aSig;
2103
2104 FloatRoundMode user_rnd_mode;
2105 FloatX80RoundPrec user_rnd_prec;
2106
2107 int32_t compact;
2108 floatx80 fp0, fp1, fp2, one;
2109
2110 aSig = extractFloatx80Frac(a);
2111 aExp = extractFloatx80Exp(a);
2112 aSign = extractFloatx80Sign(a);
2113
2114 if (aExp == 0x7FFF && (uint64_t) (aSig << 1)) {
2115 return propagateFloatx80NaNOneArg(a, status);
2116 }
2117
2118 if (aExp == 0 && aSig == 0) {
2119 return packFloatx80(aSign, 0, 0);
2120 }
2121
2122 compact = floatx80_make_compact(aExp, aSig);
2123
2124 if (compact >= 0x3FFF8000) {
2125 if (aExp == one_exp && aSig == one_sig) {
2126 float_raise(float_flag_inexact, status);
2127 a = packFloatx80(aSign, piby2_exp, pi_sig);
2128 return floatx80_move(a, status);
2129 } else {
2130 float_raise(float_flag_invalid, status);
2131 return floatx80_default_nan(status);
2132 }
2133
2134 }
2135
2136 user_rnd_mode = status->float_rounding_mode;
2137 user_rnd_prec = status->floatx80_rounding_precision;
2138 status->float_rounding_mode = float_round_nearest_even;
2139 status->floatx80_rounding_precision = floatx80_precision_x;
2140
2141 one = packFloatx80(0, one_exp, one_sig);
2142 fp0 = a;
2143
2144 fp1 = floatx80_sub(one, fp0, status);
2145 fp2 = floatx80_add(one, fp0, status);
2146 fp1 = floatx80_mul(fp2, fp1, status);
2147 fp1 = floatx80_sqrt(fp1, status);
2148 fp0 = floatx80_div(fp0, fp1, status);
2149
2150 status->float_rounding_mode = user_rnd_mode;
2151 status->floatx80_rounding_precision = user_rnd_prec;
2152
2153 a = floatx80_atan(fp0, status);
2154
2155 float_raise(float_flag_inexact, status);
2156
2157 return a;
2158}
2159
2160
2161
2162
2163
2164floatx80 floatx80_acos(floatx80 a, float_status *status)
2165{
2166 bool aSign;
2167 int32_t aExp;
2168 uint64_t aSig;
2169
2170 FloatRoundMode user_rnd_mode;
2171 FloatX80RoundPrec user_rnd_prec;
2172
2173 int32_t compact;
2174 floatx80 fp0, fp1, one;
2175
2176 aSig = extractFloatx80Frac(a);
2177 aExp = extractFloatx80Exp(a);
2178 aSign = extractFloatx80Sign(a);
2179
2180 if (aExp == 0x7FFF && (uint64_t) (aSig << 1)) {
2181 return propagateFloatx80NaNOneArg(a, status);
2182 }
2183 if (aExp == 0 && aSig == 0) {
2184 float_raise(float_flag_inexact, status);
2185 return roundAndPackFloatx80(status->floatx80_rounding_precision, 0,
2186 piby2_exp, pi_sig, 0, status);
2187 }
2188
2189 compact = floatx80_make_compact(aExp, aSig);
2190
2191 if (compact >= 0x3FFF8000) {
2192 if (aExp == one_exp && aSig == one_sig) {
2193 if (aSign) {
2194 a = packFloatx80(0, pi_exp, pi_sig);
2195 float_raise(float_flag_inexact, status);
2196 return floatx80_move(a, status);
2197 } else {
2198 return packFloatx80(0, 0, 0);
2199 }
2200 } else {
2201 float_raise(float_flag_invalid, status);
2202 return floatx80_default_nan(status);
2203 }
2204 }
2205
2206 user_rnd_mode = status->float_rounding_mode;
2207 user_rnd_prec = status->floatx80_rounding_precision;
2208 status->float_rounding_mode = float_round_nearest_even;
2209 status->floatx80_rounding_precision = floatx80_precision_x;
2210
2211 one = packFloatx80(0, one_exp, one_sig);
2212 fp0 = a;
2213
2214 fp1 = floatx80_add(one, fp0, status);
2215 fp0 = floatx80_sub(one, fp0, status);
2216 fp0 = floatx80_div(fp0, fp1, status);
2217 fp0 = floatx80_sqrt(fp0, status);
2218 fp0 = floatx80_atan(fp0, status);
2219
2220 status->float_rounding_mode = user_rnd_mode;
2221 status->floatx80_rounding_precision = user_rnd_prec;
2222
2223 a = floatx80_add(fp0, fp0, status);
2224
2225 float_raise(float_flag_inexact, status);
2226
2227 return a;
2228}
2229
2230
2231
2232
2233
2234floatx80 floatx80_atanh(floatx80 a, float_status *status)
2235{
2236 bool aSign;
2237 int32_t aExp;
2238 uint64_t aSig;
2239
2240 FloatRoundMode user_rnd_mode;
2241 FloatX80RoundPrec user_rnd_prec;
2242
2243 int32_t compact;
2244 floatx80 fp0, fp1, fp2, one;
2245
2246 aSig = extractFloatx80Frac(a);
2247 aExp = extractFloatx80Exp(a);
2248 aSign = extractFloatx80Sign(a);
2249
2250 if (aExp == 0x7FFF && (uint64_t) (aSig << 1)) {
2251 return propagateFloatx80NaNOneArg(a, status);
2252 }
2253
2254 if (aExp == 0 && aSig == 0) {
2255 return packFloatx80(aSign, 0, 0);
2256 }
2257
2258 compact = floatx80_make_compact(aExp, aSig);
2259
2260 if (compact >= 0x3FFF8000) {
2261 if (aExp == one_exp && aSig == one_sig) {
2262 float_raise(float_flag_divbyzero, status);
2263 return packFloatx80(aSign, floatx80_infinity.high,
2264 floatx80_infinity.low);
2265 } else {
2266 float_raise(float_flag_invalid, status);
2267 return floatx80_default_nan(status);
2268 }
2269 }
2270
2271 user_rnd_mode = status->float_rounding_mode;
2272 user_rnd_prec = status->floatx80_rounding_precision;
2273 status->float_rounding_mode = float_round_nearest_even;
2274 status->floatx80_rounding_precision = floatx80_precision_x;
2275
2276 one = packFloatx80(0, one_exp, one_sig);
2277 fp2 = packFloatx80(aSign, 0x3FFE, one_sig);
2278 fp0 = packFloatx80(0, aExp, aSig);
2279 fp1 = packFloatx80(1, aExp, aSig);
2280 fp0 = floatx80_add(fp0, fp0, status);
2281 fp1 = floatx80_add(fp1, one, status);
2282 fp0 = floatx80_div(fp0, fp1, status);
2283 fp0 = floatx80_lognp1(fp0, status);
2284
2285 status->float_rounding_mode = user_rnd_mode;
2286 status->floatx80_rounding_precision = user_rnd_prec;
2287
2288 a = floatx80_mul(fp0, fp2,
2289 status);
2290
2291 float_raise(float_flag_inexact, status);
2292
2293 return a;
2294}
2295
2296
2297
2298
2299
2300floatx80 floatx80_etoxm1(floatx80 a, float_status *status)
2301{
2302 bool aSign;
2303 int32_t aExp;
2304 uint64_t aSig;
2305
2306 FloatRoundMode user_rnd_mode;
2307 FloatX80RoundPrec user_rnd_prec;
2308
2309 int32_t compact, n, j, m, m1;
2310 floatx80 fp0, fp1, fp2, fp3, l2, sc, onebysc;
2311
2312 aSig = extractFloatx80Frac(a);
2313 aExp = extractFloatx80Exp(a);
2314 aSign = extractFloatx80Sign(a);
2315
2316 if (aExp == 0x7FFF) {
2317 if ((uint64_t) (aSig << 1)) {
2318 return propagateFloatx80NaNOneArg(a, status);
2319 }
2320 if (aSign) {
2321 return packFloatx80(aSign, one_exp, one_sig);
2322 }
2323 return packFloatx80(0, floatx80_infinity.high,
2324 floatx80_infinity.low);
2325 }
2326
2327 if (aExp == 0 && aSig == 0) {
2328 return packFloatx80(aSign, 0, 0);
2329 }
2330
2331 user_rnd_mode = status->float_rounding_mode;
2332 user_rnd_prec = status->floatx80_rounding_precision;
2333 status->float_rounding_mode = float_round_nearest_even;
2334 status->floatx80_rounding_precision = floatx80_precision_x;
2335
2336 if (aExp >= 0x3FFD) {
2337 compact = floatx80_make_compact(aExp, aSig);
2338
2339 if (compact <= 0x4004C215) {
2340 fp0 = a;
2341 fp1 = a;
2342 fp0 = floatx80_mul(fp0, float32_to_floatx80(
2343 make_float32(0x42B8AA3B), status),
2344 status);
2345 n = floatx80_to_int32(fp0, status);
2346 fp0 = int32_to_floatx80(n, status);
2347
2348 j = n & 0x3F;
2349 m = n / 64;
2350 if (n < 0 && j) {
2351
2352
2353
2354
2355 m--;
2356 }
2357 m1 = -m;
2358
2359
2360
2361 fp2 = fp0;
2362 fp0 = floatx80_mul(fp0, float32_to_floatx80(
2363 make_float32(0xBC317218), status),
2364 status);
2365 l2 = packFloatx80(0, 0x3FDC, UINT64_C(0x82E308654361C4C6));
2366 fp2 = floatx80_mul(fp2, l2, status);
2367 fp0 = floatx80_add(fp0, fp1, status);
2368 fp0 = floatx80_add(fp0, fp2, status);
2369
2370 fp1 = floatx80_mul(fp0, fp0, status);
2371 fp2 = float32_to_floatx80(make_float32(0x3950097B),
2372 status);
2373 fp2 = floatx80_mul(fp2, fp1, status);
2374 fp3 = floatx80_mul(float32_to_floatx80(make_float32(0x3AB60B6A),
2375 status), fp1, status);
2376 fp2 = floatx80_add(fp2, float64_to_floatx80(
2377 make_float64(0x3F81111111174385), status),
2378 status);
2379 fp3 = floatx80_add(fp3, float64_to_floatx80(
2380 make_float64(0x3FA5555555554F5A), status),
2381 status);
2382 fp2 = floatx80_mul(fp2, fp1, status);
2383 fp3 = floatx80_mul(fp3, fp1, status);
2384 fp2 = floatx80_add(fp2, float64_to_floatx80(
2385 make_float64(0x3FC5555555555555), status),
2386 status);
2387 fp3 = floatx80_add(fp3, float32_to_floatx80(
2388 make_float32(0x3F000000), status),
2389 status);
2390 fp2 = floatx80_mul(fp2, fp1,
2391 status);
2392 fp1 = floatx80_mul(fp1, fp3,
2393 status);
2394 fp2 = floatx80_mul(fp2, fp0,
2395 status);
2396 fp0 = floatx80_add(fp0, fp1,
2397 status);
2398 fp0 = floatx80_add(fp0, fp2, status);
2399
2400 fp0 = floatx80_mul(fp0, exp_tbl[j],
2401 status);
2402
2403 if (m >= 64) {
2404 fp1 = float32_to_floatx80(exp_tbl2[j], status);
2405 onebysc = packFloatx80(1, m1 + 0x3FFF, one_sig);
2406 fp1 = floatx80_add(fp1, onebysc, status);
2407 fp0 = floatx80_add(fp0, fp1, status);
2408 fp0 = floatx80_add(fp0, exp_tbl[j], status);
2409 } else if (m < -3) {
2410 fp0 = floatx80_add(fp0, float32_to_floatx80(exp_tbl2[j],
2411 status), status);
2412 fp0 = floatx80_add(fp0, exp_tbl[j], status);
2413 onebysc = packFloatx80(1, m1 + 0x3FFF, one_sig);
2414 fp0 = floatx80_add(fp0, onebysc, status);
2415 } else {
2416 fp1 = exp_tbl[j];
2417 fp0 = floatx80_add(fp0, float32_to_floatx80(exp_tbl2[j],
2418 status), status);
2419 onebysc = packFloatx80(1, m1 + 0x3FFF, one_sig);
2420 fp1 = floatx80_add(fp1, onebysc, status);
2421 fp0 = floatx80_add(fp0, fp1, status);
2422 }
2423
2424 sc = packFloatx80(0, m + 0x3FFF, one_sig);
2425
2426 status->float_rounding_mode = user_rnd_mode;
2427 status->floatx80_rounding_precision = user_rnd_prec;
2428
2429 a = floatx80_mul(fp0, sc, status);
2430
2431 float_raise(float_flag_inexact, status);
2432
2433 return a;
2434 } else {
2435 if (aSign) {
2436 fp0 = float32_to_floatx80(make_float32(0xBF800000),
2437 status);
2438
2439 status->float_rounding_mode = user_rnd_mode;
2440 status->floatx80_rounding_precision = user_rnd_prec;
2441
2442 a = floatx80_add(fp0, float32_to_floatx80(
2443 make_float32(0x00800000), status),
2444 status);
2445
2446 float_raise(float_flag_inexact, status);
2447
2448 return a;
2449 } else {
2450 status->float_rounding_mode = user_rnd_mode;
2451 status->floatx80_rounding_precision = user_rnd_prec;
2452
2453 return floatx80_etox(a, status);
2454 }
2455 }
2456 } else {
2457 if (aExp >= 0x3FBE) {
2458 fp0 = a;
2459 fp0 = floatx80_mul(fp0, fp0, status);
2460 fp1 = float32_to_floatx80(make_float32(0x2F30CAA8),
2461 status);
2462 fp1 = floatx80_mul(fp1, fp0, status);
2463 fp2 = float32_to_floatx80(make_float32(0x310F8290),
2464 status);
2465 fp1 = floatx80_add(fp1, float32_to_floatx80(
2466 make_float32(0x32D73220), status),
2467 status);
2468 fp2 = floatx80_mul(fp2, fp0, status);
2469 fp1 = floatx80_mul(fp1, fp0, status);
2470 fp2 = floatx80_add(fp2, float32_to_floatx80(
2471 make_float32(0x3493F281), status),
2472 status);
2473 fp1 = floatx80_add(fp1, float64_to_floatx80(
2474 make_float64(0x3EC71DE3A5774682), status),
2475 status);
2476 fp2 = floatx80_mul(fp2, fp0, status);
2477 fp1 = floatx80_mul(fp1, fp0, status);
2478 fp2 = floatx80_add(fp2, float64_to_floatx80(
2479 make_float64(0x3EFA01A019D7CB68), status),
2480 status);
2481 fp1 = floatx80_add(fp1, float64_to_floatx80(
2482 make_float64(0x3F2A01A01A019DF3), status),
2483 status);
2484 fp2 = floatx80_mul(fp2, fp0, status);
2485 fp1 = floatx80_mul(fp1, fp0, status);
2486 fp2 = floatx80_add(fp2, float64_to_floatx80(
2487 make_float64(0x3F56C16C16C170E2), status),
2488 status);
2489 fp1 = floatx80_add(fp1, float64_to_floatx80(
2490 make_float64(0x3F81111111111111), status),
2491 status);
2492 fp2 = floatx80_mul(fp2, fp0, status);
2493 fp1 = floatx80_mul(fp1, fp0, status);
2494 fp2 = floatx80_add(fp2, float64_to_floatx80(
2495 make_float64(0x3FA5555555555555), status),
2496 status);
2497 fp3 = packFloatx80(0, 0x3FFC, UINT64_C(0xAAAAAAAAAAAAAAAB));
2498 fp1 = floatx80_add(fp1, fp3, status);
2499 fp2 = floatx80_mul(fp2, fp0, status);
2500 fp1 = floatx80_mul(fp1, fp0, status);
2501
2502 fp2 = floatx80_mul(fp2, fp0, status);
2503 fp1 = floatx80_mul(fp1, a, status);
2504
2505 fp0 = floatx80_mul(fp0, float32_to_floatx80(
2506 make_float32(0x3F000000), status),
2507 status);
2508 fp1 = floatx80_add(fp1, fp2, status);
2509 fp0 = floatx80_add(fp0, fp1, status);
2510
2511 status->float_rounding_mode = user_rnd_mode;
2512 status->floatx80_rounding_precision = user_rnd_prec;
2513
2514 a = floatx80_add(fp0, a, status);
2515
2516 float_raise(float_flag_inexact, status);
2517
2518 return a;
2519 } else {
2520 sc = packFloatx80(1, 1, one_sig);
2521 fp0 = a;
2522
2523 if (aExp < 0x0033) {
2524 fp0 = floatx80_mul(fp0, float64_to_floatx80(
2525 make_float64(0x48B0000000000000), status),
2526 status);
2527 fp0 = floatx80_add(fp0, sc, status);
2528
2529 status->float_rounding_mode = user_rnd_mode;
2530 status->floatx80_rounding_precision = user_rnd_prec;
2531
2532 a = floatx80_mul(fp0, float64_to_floatx80(
2533 make_float64(0x3730000000000000), status),
2534 status);
2535 } else {
2536 status->float_rounding_mode = user_rnd_mode;
2537 status->floatx80_rounding_precision = user_rnd_prec;
2538
2539 a = floatx80_add(fp0, sc, status);
2540 }
2541
2542 float_raise(float_flag_inexact, status);
2543
2544 return a;
2545 }
2546 }
2547}
2548
2549
2550
2551
2552
2553floatx80 floatx80_tanh(floatx80 a, float_status *status)
2554{
2555 bool aSign, vSign;
2556 int32_t aExp, vExp;
2557 uint64_t aSig, vSig;
2558
2559 FloatRoundMode user_rnd_mode;
2560 FloatX80RoundPrec user_rnd_prec;
2561
2562 int32_t compact;
2563 floatx80 fp0, fp1;
2564 uint32_t sign;
2565
2566 aSig = extractFloatx80Frac(a);
2567 aExp = extractFloatx80Exp(a);
2568 aSign = extractFloatx80Sign(a);
2569
2570 if (aExp == 0x7FFF) {
2571 if ((uint64_t) (aSig << 1)) {
2572 return propagateFloatx80NaNOneArg(a, status);
2573 }
2574 return packFloatx80(aSign, one_exp, one_sig);
2575 }
2576
2577 if (aExp == 0 && aSig == 0) {
2578 return packFloatx80(aSign, 0, 0);
2579 }
2580
2581 user_rnd_mode = status->float_rounding_mode;
2582 user_rnd_prec = status->floatx80_rounding_precision;
2583 status->float_rounding_mode = float_round_nearest_even;
2584 status->floatx80_rounding_precision = floatx80_precision_x;
2585
2586 compact = floatx80_make_compact(aExp, aSig);
2587
2588 if (compact < 0x3FD78000 || compact > 0x3FFFDDCE) {
2589
2590 if (compact < 0x3FFF8000) {
2591
2592 status->float_rounding_mode = user_rnd_mode;
2593 status->floatx80_rounding_precision = user_rnd_prec;
2594
2595 a = floatx80_move(a, status);
2596
2597 float_raise(float_flag_inexact, status);
2598
2599 return a;
2600 } else {
2601 if (compact > 0x40048AA1) {
2602
2603 sign = 0x3F800000;
2604 sign |= aSign ? 0x80000000 : 0x00000000;
2605 fp0 = float32_to_floatx80(make_float32(sign), status);
2606 sign &= 0x80000000;
2607 sign ^= 0x80800000;
2608
2609 status->float_rounding_mode = user_rnd_mode;
2610 status->floatx80_rounding_precision = user_rnd_prec;
2611
2612 a = floatx80_add(fp0, float32_to_floatx80(make_float32(sign),
2613 status), status);
2614
2615 float_raise(float_flag_inexact, status);
2616
2617 return a;
2618 } else {
2619 fp0 = packFloatx80(0, aExp + 1, aSig);
2620 fp0 = floatx80_etox(fp0, status);
2621 fp0 = floatx80_add(fp0, float32_to_floatx80(
2622 make_float32(0x3F800000),
2623 status), status);
2624 sign = aSign ? 0x80000000 : 0x00000000;
2625 fp1 = floatx80_div(float32_to_floatx80(make_float32(
2626 sign ^ 0xC0000000), status), fp0,
2627 status);
2628 fp0 = float32_to_floatx80(make_float32(sign | 0x3F800000),
2629 status);
2630
2631 status->float_rounding_mode = user_rnd_mode;
2632 status->floatx80_rounding_precision = user_rnd_prec;
2633
2634 a = floatx80_add(fp1, fp0, status);
2635
2636 float_raise(float_flag_inexact, status);
2637
2638 return a;
2639 }
2640 }
2641 } else {
2642 fp0 = packFloatx80(0, aExp + 1, aSig);
2643 fp0 = floatx80_etoxm1(fp0, status);
2644 fp1 = floatx80_add(fp0, float32_to_floatx80(make_float32(0x40000000),
2645 status),
2646 status);
2647
2648 vSign = extractFloatx80Sign(fp1);
2649 vExp = extractFloatx80Exp(fp1);
2650 vSig = extractFloatx80Frac(fp1);
2651
2652 fp1 = packFloatx80(vSign ^ aSign, vExp, vSig);
2653
2654 status->float_rounding_mode = user_rnd_mode;
2655 status->floatx80_rounding_precision = user_rnd_prec;
2656
2657 a = floatx80_div(fp0, fp1, status);
2658
2659 float_raise(float_flag_inexact, status);
2660
2661 return a;
2662 }
2663}
2664
2665
2666
2667
2668
2669floatx80 floatx80_sinh(floatx80 a, float_status *status)
2670{
2671 bool aSign;
2672 int32_t aExp;
2673 uint64_t aSig;
2674
2675 FloatRoundMode user_rnd_mode;
2676 FloatX80RoundPrec user_rnd_prec;
2677
2678 int32_t compact;
2679 floatx80 fp0, fp1, fp2;
2680 float32 fact;
2681
2682 aSig = extractFloatx80Frac(a);
2683 aExp = extractFloatx80Exp(a);
2684 aSign = extractFloatx80Sign(a);
2685
2686 if (aExp == 0x7FFF) {
2687 if ((uint64_t) (aSig << 1)) {
2688 return propagateFloatx80NaNOneArg(a, status);
2689 }
2690 return packFloatx80(aSign, floatx80_infinity.high,
2691 floatx80_infinity.low);
2692 }
2693
2694 if (aExp == 0 && aSig == 0) {
2695 return packFloatx80(aSign, 0, 0);
2696 }
2697
2698 user_rnd_mode = status->float_rounding_mode;
2699 user_rnd_prec = status->floatx80_rounding_precision;
2700 status->float_rounding_mode = float_round_nearest_even;
2701 status->floatx80_rounding_precision = floatx80_precision_x;
2702
2703 compact = floatx80_make_compact(aExp, aSig);
2704
2705 if (compact > 0x400CB167) {
2706
2707 if (compact > 0x400CB2B3) {
2708 status->float_rounding_mode = user_rnd_mode;
2709 status->floatx80_rounding_precision = user_rnd_prec;
2710
2711 return roundAndPackFloatx80(status->floatx80_rounding_precision,
2712 aSign, 0x8000, aSig, 0, status);
2713 } else {
2714 fp0 = floatx80_abs(a);
2715 fp0 = floatx80_sub(fp0, float64_to_floatx80(
2716 make_float64(0x40C62D38D3D64634), status),
2717 status);
2718 fp0 = floatx80_sub(fp0, float64_to_floatx80(
2719 make_float64(0x3D6F90AEB1E75CC7), status),
2720 status);
2721 fp0 = floatx80_etox(fp0, status);
2722 fp2 = packFloatx80(aSign, 0x7FFB, one_sig);
2723
2724 status->float_rounding_mode = user_rnd_mode;
2725 status->floatx80_rounding_precision = user_rnd_prec;
2726
2727 a = floatx80_mul(fp0, fp2, status);
2728
2729 float_raise(float_flag_inexact, status);
2730
2731 return a;
2732 }
2733 } else {
2734 fp0 = floatx80_abs(a);
2735 fp0 = floatx80_etoxm1(fp0, status);
2736 fp1 = floatx80_add(fp0, float32_to_floatx80(make_float32(0x3F800000),
2737 status), status);
2738 fp2 = fp0;
2739 fp0 = floatx80_div(fp0, fp1, status);
2740 fp0 = floatx80_add(fp0, fp2, status);
2741
2742 fact = packFloat32(aSign, 0x7E, 0);
2743
2744 status->float_rounding_mode = user_rnd_mode;
2745 status->floatx80_rounding_precision = user_rnd_prec;
2746
2747 a = floatx80_mul(fp0, float32_to_floatx80(fact, status), status);
2748
2749 float_raise(float_flag_inexact, status);
2750
2751 return a;
2752 }
2753}
2754
2755
2756
2757
2758
2759floatx80 floatx80_cosh(floatx80 a, float_status *status)
2760{
2761 int32_t aExp;
2762 uint64_t aSig;
2763
2764 FloatRoundMode user_rnd_mode;
2765 FloatX80RoundPrec user_rnd_prec;
2766
2767 int32_t compact;
2768 floatx80 fp0, fp1;
2769
2770 aSig = extractFloatx80Frac(a);
2771 aExp = extractFloatx80Exp(a);
2772
2773 if (aExp == 0x7FFF) {
2774 if ((uint64_t) (aSig << 1)) {
2775 return propagateFloatx80NaNOneArg(a, status);
2776 }
2777 return packFloatx80(0, floatx80_infinity.high,
2778 floatx80_infinity.low);
2779 }
2780
2781 if (aExp == 0 && aSig == 0) {
2782 return packFloatx80(0, one_exp, one_sig);
2783 }
2784
2785 user_rnd_mode = status->float_rounding_mode;
2786 user_rnd_prec = status->floatx80_rounding_precision;
2787 status->float_rounding_mode = float_round_nearest_even;
2788 status->floatx80_rounding_precision = floatx80_precision_x;
2789
2790 compact = floatx80_make_compact(aExp, aSig);
2791
2792 if (compact > 0x400CB167) {
2793 if (compact > 0x400CB2B3) {
2794 status->float_rounding_mode = user_rnd_mode;
2795 status->floatx80_rounding_precision = user_rnd_prec;
2796 return roundAndPackFloatx80(status->floatx80_rounding_precision, 0,
2797 0x8000, one_sig, 0, status);
2798 } else {
2799 fp0 = packFloatx80(0, aExp, aSig);
2800 fp0 = floatx80_sub(fp0, float64_to_floatx80(
2801 make_float64(0x40C62D38D3D64634), status),
2802 status);
2803 fp0 = floatx80_sub(fp0, float64_to_floatx80(
2804 make_float64(0x3D6F90AEB1E75CC7), status),
2805 status);
2806 fp0 = floatx80_etox(fp0, status);
2807 fp1 = packFloatx80(0, 0x7FFB, one_sig);
2808
2809 status->float_rounding_mode = user_rnd_mode;
2810 status->floatx80_rounding_precision = user_rnd_prec;
2811
2812 a = floatx80_mul(fp0, fp1, status);
2813
2814 float_raise(float_flag_inexact, status);
2815
2816 return a;
2817 }
2818 }
2819
2820 fp0 = packFloatx80(0, aExp, aSig);
2821 fp0 = floatx80_etox(fp0, status);
2822 fp0 = floatx80_mul(fp0, float32_to_floatx80(make_float32(0x3F000000),
2823 status), status);
2824 fp1 = float32_to_floatx80(make_float32(0x3E800000), status);
2825 fp1 = floatx80_div(fp1, fp0, status);
2826
2827 status->float_rounding_mode = user_rnd_mode;
2828 status->floatx80_rounding_precision = user_rnd_prec;
2829
2830 a = floatx80_add(fp0, fp1, status);
2831
2832 float_raise(float_flag_inexact, status);
2833
2834 return a;
2835}
2836