|
|
1.1 root 1:
2: /*============================================================================
3:
4: This C source file is an extension to the SoftFloat IEC/IEEE Floating-point
5: Arithmetic Package, Release 2a.
6:
7: =============================================================================*/
8:
9: #include "softfloat.h"
10:
11: /*----------------------------------------------------------------------------
12: | Methods for detecting special conditions for mathematical functions
13: | supported by MC68881 and MC68862 mathematical coprocessor.
14: *----------------------------------------------------------------------------*/
15:
16: #define pi_sig0 LIT64(0xc90fdaa22168c234)
17: #define pi_sig1 LIT64(0xc4c6628b80dc1cd1)
18:
19: #define pi_exp 0x4000
20: #define piby2_exp 0x3FFF
21: #define piby4_exp 0x3FFE
22:
23: #define one_exp 0x3FFF
24: #define one_sig LIT64(0x8000000000000000)
25:
26: /*----------------------------------------------------------------------------
27: | Arc cosine
28: *----------------------------------------------------------------------------*/
29:
30: floatx80 floatx80_acos_check(floatx80 a, flag *e)
31: {
32: flag aSign;
33: int32 aExp;
34: bits64 aSig;
35:
36: *e = 1;
37:
38: aSig = extractFloatx80Frac(a);
39: aExp = extractFloatx80Exp(a);
40: aSign = extractFloatx80Sign(a);
41:
42: if (aExp == 0x7FFF && (bits64) (aSig<<1)) {
43: return propagateFloatx80NaNOneArg(a);
44: }
45:
46: if (aExp > one_exp || (aExp == one_exp && aSig > one_sig)) {
47: float_raise(float_flag_invalid);
48: a.low = floatx80_default_nan_low;
49: a.high = floatx80_default_nan_high;
50: return a;
51: }
52:
53: if (aExp == 0) {
54: if (aSig == 0) return roundAndPackFloatx80(floatx80_rounding_precision,
55: 0, piby2_exp, pi_sig0, pi_sig1);
56: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
57: }
58:
59: *e = 0;
60: return a;
61: }
62:
63: /*----------------------------------------------------------------------------
64: | Arc sine
65: *----------------------------------------------------------------------------*/
66:
67: floatx80 floatx80_asin_check(floatx80 a, flag *e)
68: {
69: flag aSign;
70: int32 aExp;
71: bits64 aSig;
72:
73: *e = 1;
74:
75: aSig = extractFloatx80Frac(a);
76: aExp = extractFloatx80Exp(a);
77: aSign = extractFloatx80Sign(a);
78:
79: if (aExp == 0x7FFF && (bits64) (aSig<<1)) {
80: return propagateFloatx80NaNOneArg(a);
81: }
82:
83: if (aExp > one_exp || (aExp == one_exp && aSig > one_sig)) {
84: float_raise(float_flag_invalid);
85: a.low = floatx80_default_nan_low;
86: a.high = floatx80_default_nan_high;
87: return a;
88: }
89:
90: if (aExp == 0) {
91: if (aSig == 0) return packFloatx80(aSign, 0, 0);
92: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
93: }
94:
95: *e = 0;
96: return a;
97: }
98:
99: /*----------------------------------------------------------------------------
100: | Arc tangent
101: *----------------------------------------------------------------------------*/
102:
103: floatx80 floatx80_atan_check(floatx80 a, flag *e)
104: {
105: flag aSign;
106: int32 aExp;
107: bits64 aSig;
108:
109: *e = 1;
110:
111: aSig = extractFloatx80Frac(a);
112: aExp = extractFloatx80Exp(a);
113: aSign = extractFloatx80Sign(a);
114:
115: if (aExp == 0x7FFF) {
116: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
117: return roundAndPackFloatx80(floatx80_rounding_precision,
118: aSign, piby2_exp, pi_sig0, pi_sig1);
119: }
120:
121: if (aExp == 0) {
122: if (aSig == 0) return packFloatx80(aSign, 0, 0);
123: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
124: }
125:
126: *e = 0;
127: return a;
128: }
129:
130: /*----------------------------------------------------------------------------
131: | Hyperbolic arc tangent
132: *----------------------------------------------------------------------------*/
133:
134: floatx80 floatx80_atanh_check(floatx80 a, flag *e)
135: {
136: flag aSign;
137: int32 aExp;
138: bits64 aSig;
139:
140: *e = 1;
141:
142: aSig = extractFloatx80Frac(a);
143: aExp = extractFloatx80Exp(a);
144: aSign = extractFloatx80Sign(a);
145:
146: if (aExp == 0x7FFF && (bits64) (aSig<<1)) {
147: return propagateFloatx80NaNOneArg(a);
148: }
149:
150: if (aExp >= one_exp) {
151: if (aExp == one_exp && aSig == one_sig) {
152: float_raise(float_flag_divbyzero);
153: packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low);
154: }
155: float_raise(float_flag_invalid);
156: a.low = floatx80_default_nan_low;
157: a.high = floatx80_default_nan_high;
158: return a;
159: }
160:
161: if (aExp == 0) {
162: if (aSig == 0) return packFloatx80(aSign, 0, 0);
163: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
164: }
165:
166: *e = 0;
167: return a;
168: }
169:
170: /*----------------------------------------------------------------------------
171: | Cosine
172: *----------------------------------------------------------------------------*/
173:
174: floatx80 floatx80_cos_check(floatx80 a, flag *e)
175: {
176: flag aSign;
177: int32 aExp;
178: bits64 aSig;
179:
180: *e = 1;
181:
182: aSig = extractFloatx80Frac(a);
183: aExp = extractFloatx80Exp(a);
184: aSign = extractFloatx80Sign(a);
185:
186: if (aExp == 0x7FFF) {
187: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
188: float_raise(float_flag_invalid);
189: a.low = floatx80_default_nan_low;
190: a.high = floatx80_default_nan_high;
191: return a;
192: }
193:
194: if (aExp == 0) {
195: if (aSig == 0) return packFloatx80(0, one_exp, one_sig);
196: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
197: }
198:
199: *e = 0;
200: return a;
201: }
202:
203: /*----------------------------------------------------------------------------
204: | Hyperbolic cosine
205: *----------------------------------------------------------------------------*/
206:
207: floatx80 floatx80_cosh_check(floatx80 a, flag *e)
208: {
209: flag aSign;
210: int32 aExp;
211: bits64 aSig;
212:
213: *e = 1;
214:
215: aSig = extractFloatx80Frac(a);
216: aExp = extractFloatx80Exp(a);
217: aSign = extractFloatx80Sign(a);
218:
219: if (aExp == 0x7FFF) {
220: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
221: return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
222: }
223:
224: if (aExp == 0) {
225: if (aSig == 0) return packFloatx80(0, one_exp, one_sig);
226: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
227: }
228:
229: *e = 0;
230: return a;
231: }
232:
233: /*----------------------------------------------------------------------------
234: | e to x
235: *----------------------------------------------------------------------------*/
236:
237: floatx80 floatx80_etox_check(floatx80 a, flag *e)
238: {
239: flag aSign;
240: int32 aExp;
241: bits64 aSig;
242:
243: *e = 1;
244:
245: aSig = extractFloatx80Frac(a);
246: aExp = extractFloatx80Exp(a);
247: aSign = extractFloatx80Sign(a);
248:
249: if (aExp == 0x7FFF) {
250: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
251: if (aSign) return packFloatx80(0, 0, 0);
252: return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
253: }
254:
255: if (aExp == 0) {
256: if (aSig == 0) return packFloatx80(0, one_exp, one_sig);
257: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
258: }
259:
260: *e = 0;
261: return a;
262: }
263:
264: /*----------------------------------------------------------------------------
265: | e to x minus 1
266: *----------------------------------------------------------------------------*/
267:
268: floatx80 floatx80_etoxm1_check(floatx80 a, flag *e)
269: {
270: flag aSign;
271: int32 aExp;
272: bits64 aSig;
273:
274: *e = 1;
275:
276: aSig = extractFloatx80Frac(a);
277: aExp = extractFloatx80Exp(a);
278: aSign = extractFloatx80Sign(a);
279:
280: if (aExp == 0x7FFF) {
281: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
282: if (aSign) return packFloatx80(aSign, one_exp, one_sig);
283: return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
284: }
285:
286: if (aExp == 0) {
287: if (aSig == 0) return packFloatx80(aSign, 0, 0);
288: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
289: }
290:
291: *e = 0;
292: return a;
293: }
294:
295: /*----------------------------------------------------------------------------
296: | Log base 10
297: *----------------------------------------------------------------------------*/
298:
299: floatx80 floatx80_log10_check(floatx80 a, flag *e)
300: {
301: flag aSign;
302: int32 aExp;
303: bits64 aSig;
304:
305: *e = 1;
306:
307: aSig = extractFloatx80Frac(a);
308: aExp = extractFloatx80Exp(a);
309: aSign = extractFloatx80Sign(a);
310:
311: if (aExp == 0x7FFF) {
312: if ((bits64) (aSig<<1)) propagateFloatx80NaNOneArg(a);
313: if (aSign == 0)
314: return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
315: }
316:
317: if (aExp == 0) {
318: if (aSig == 0) {
319: float_raise(float_flag_divbyzero);
320: return packFloatx80(1, 0x7FFF, floatx80_default_infinity_low);
321: }
322: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
323: }
324:
325: if (aSign) {
326: float_raise(float_flag_invalid);
327: a.low = floatx80_default_nan_low;
328: a.high = floatx80_default_nan_high;
329: return a;
330: }
331:
332: *e = 0;
333: return a;
334: }
335:
336: /*----------------------------------------------------------------------------
337: | Log base 2
338: *----------------------------------------------------------------------------*/
339:
340: floatx80 floatx80_log2_check(floatx80 a, flag *e)
341: {
342: flag aSign;
343: int32 aExp;
344: bits64 aSig;
345:
346: *e = 1;
347:
348: aSig = extractFloatx80Frac(a);
349: aExp = extractFloatx80Exp(a);
350: aSign = extractFloatx80Sign(a);
351:
352: if (aExp == 0x7FFF) {
353: if ((bits64) (aSig<<1)) propagateFloatx80NaNOneArg(a);
354: if (aSign == 0)
355: return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
356: }
357:
358: if (aExp == 0) {
359: if (aSig == 0) {
360: float_raise(float_flag_divbyzero);
361: return packFloatx80(1, 0x7FFF, floatx80_default_infinity_low);
362: }
363: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
364: }
365:
366: if (aSign) {
367: float_raise(float_flag_invalid);
368: a.low = floatx80_default_nan_low;
369: a.high = floatx80_default_nan_high;
370: return a;
371: }
372:
373: *e = 0;
374: return a;
375: }
376:
377: /*----------------------------------------------------------------------------
378: | Log base e
379: *----------------------------------------------------------------------------*/
380:
381: floatx80 floatx80_logn_check(floatx80 a, flag *e)
382: {
383: flag aSign;
384: int32 aExp;
385: bits64 aSig;
386:
387: *e = 1;
388:
389: aSig = extractFloatx80Frac(a);
390: aExp = extractFloatx80Exp(a);
391: aSign = extractFloatx80Sign(a);
392:
393: if (aExp == 0x7FFF) {
394: if ((bits64) (aSig<<1)) propagateFloatx80NaNOneArg(a);
395: if (aSign == 0)
396: return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
397: }
398:
399: if (aExp == 0) {
400: if (aSig == 0) {
401: float_raise(float_flag_divbyzero);
402: return packFloatx80(1, 0x7FFF, floatx80_default_infinity_low);
403: }
404: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
405: }
406:
407: if (aSign) {
408: float_raise(float_flag_invalid);
409: a.low = floatx80_default_nan_low;
410: a.high = floatx80_default_nan_high;
411: return a;
412: }
413:
414: *e = 0;
415: return a;
416: }
417:
418: /*----------------------------------------------------------------------------
419: | Log base e of x plus 1
420: *----------------------------------------------------------------------------*/
421:
422: floatx80 floatx80_lognp1_check(floatx80 a, flag *e)
423: {
424: flag aSign;
425: int32 aExp;
426: bits64 aSig;
427:
428: *e = 1;
429:
430: aSig = extractFloatx80Frac(a);
431: aExp = extractFloatx80Exp(a);
432: aSign = extractFloatx80Sign(a);
433:
434: if (aExp == 0x7FFF) {
435: if ((bits64) (aSig<<1)) propagateFloatx80NaNOneArg(a);
436: if (aSign) {
437: float_raise(float_flag_invalid);
438: a.low = floatx80_default_nan_low;
439: a.high = floatx80_default_nan_high;
440: return a;
441: }
442: return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
443: }
444:
445: if (aExp == 0) {
446: if (aSig == 0) return packFloatx80(aSign, 0, 0);
447: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
448: }
449:
450: if (aSign && aExp >= one_exp) {
451: if (aExp == one_exp && aSig == one_sig) {
452: float_raise(float_flag_divbyzero);
453: packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low); /* NaN? */
454: }
455: float_raise(float_flag_invalid);
456: a.low = floatx80_default_nan_low;
457: a.high = floatx80_default_nan_high;
458: return a;
459: }
460:
461: *e = 0;
462: return a;
463: }
464:
465: /*----------------------------------------------------------------------------
466: | Sine
467: *----------------------------------------------------------------------------*/
468:
469: floatx80 floatx80_sin_check(floatx80 a, flag *e)
470: {
471: flag aSign;
472: int32 aExp;
473: bits64 aSig;
474:
475: *e = 1;
476:
477: aSig = extractFloatx80Frac(a);
478: aExp = extractFloatx80Exp(a);
479: aSign = extractFloatx80Sign(a);
480:
481: if (aExp == 0x7FFF) {
482: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
483: float_raise(float_flag_invalid);
484: a.low = floatx80_default_nan_low;
485: a.high = floatx80_default_nan_high;
486: return a;
487: }
488:
489: if (aExp == 0) {
490: if (aSig == 0) return packFloatx80(aSign, 0, 0);
491: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
492: }
493:
494: *e = 0;
495: return a;
496: }
497:
498: /*----------------------------------------------------------------------------
499: | Hyperbolic sine
500: *----------------------------------------------------------------------------*/
501:
502: floatx80 floatx80_sinh_check(floatx80 a, flag *e)
503: {
504: flag aSign;
505: int32 aExp;
506: bits64 aSig;
507:
508: *e = 1;
509:
510: aSig = extractFloatx80Frac(a);
511: aExp = extractFloatx80Exp(a);
512: aSign = extractFloatx80Sign(a);
513:
514: if (aExp == 0x7FFF) {
515: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
516: return packFloatx80(aSign, 0x7FFF, floatx80_default_infinity_low);
517: }
518:
519: if (aExp == 0) {
520: if (aSig == 0) return packFloatx80(aSign, 0, 0);
521: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
522: }
523:
524: *e = 0;
525: return a;
526: }
527:
528: /*----------------------------------------------------------------------------
529: | Tangent
530: *----------------------------------------------------------------------------*/
531:
532: floatx80 floatx80_tan_check(floatx80 a, flag *e)
533: {
534: flag aSign;
535: int32 aExp;
536: bits64 aSig;
537:
538: *e = 1;
539:
540: aSig = extractFloatx80Frac(a);
541: aExp = extractFloatx80Exp(a);
542: aSign = extractFloatx80Sign(a);
543:
544: if (aExp == 0x7FFF) {
545: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
546: float_raise(float_flag_invalid);
547: a.low = floatx80_default_nan_low;
548: a.high = floatx80_default_nan_high;
549: return a;
550: }
551:
552: if (aExp == 0) {
553: if (aSig == 0) return packFloatx80(aSign, 0, 0);
554: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
555: }
556:
557: *e = 0;
558: return a;
559: }
560:
561: /*----------------------------------------------------------------------------
562: | Hyperbolic tangent
563: *----------------------------------------------------------------------------*/
564:
565: floatx80 floatx80_tanh_check(floatx80 a, flag *e)
566: {
567: flag aSign;
568: int32 aExp;
569: bits64 aSig;
570:
571: *e = 1;
572:
573: aSig = extractFloatx80Frac(a);
574: aExp = extractFloatx80Exp(a);
575: aSign = extractFloatx80Sign(a);
576:
577: if (aExp == 0x7FFF) {
578: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
579: return packFloatx80(aSign, one_exp, one_sig);
580: }
581:
582: if (aExp == 0) {
583: if (aSig == 0) return packFloatx80(aSign, 0, 0);
584: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
585: }
586:
587: *e = 0;
588: return a;
589: }
590:
591: /*----------------------------------------------------------------------------
592: | 10 to x
593: *----------------------------------------------------------------------------*/
594:
595: floatx80 floatx80_tentox_check(floatx80 a, flag *e)
596: {
597: flag aSign;
598: int32 aExp;
599: bits64 aSig;
600:
601: *e = 1;
602:
603: aSig = extractFloatx80Frac(a);
604: aExp = extractFloatx80Exp(a);
605: aSign = extractFloatx80Sign(a);
606:
607: if (aExp == 0x7FFF) {
608: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
609: if (aSign) return packFloatx80(0, 0, 0);
610: return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
611: }
612:
613: if (aExp == 0) {
614: if (aSig == 0) return packFloatx80(0, one_exp, one_sig);
615: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
616: }
617:
618: *e = 0;
619: return a;
620: }
621:
622: /*----------------------------------------------------------------------------
623: | 2 to x
624: *----------------------------------------------------------------------------*/
625:
626: floatx80 floatx80_twotox_check(floatx80 a, flag *e)
627: {
628: flag aSign;
629: int32 aExp;
630: bits64 aSig;
631:
632: *e = 1;
633:
634: aSig = extractFloatx80Frac(a);
635: aExp = extractFloatx80Exp(a);
636: aSign = extractFloatx80Sign(a);
637:
638: if (aExp == 0x7FFF) {
639: if ((bits64) (aSig<<1)) return propagateFloatx80NaNOneArg(a);
640: if (aSign) return packFloatx80(0, 0, 0);
641: return packFloatx80(0, 0x7FFF, floatx80_default_infinity_low);
642: }
643:
644: if (aExp == 0) {
645: if (aSig == 0) return packFloatx80(0, one_exp, one_sig);
646: normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
647: }
648:
649: *e = 0;
650: return a;
651: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.