Linux Audio

Check our new training course

Loading...
v5.14.15
 1// SPDX-License-Identifier: GPL-2.0-only
 2/* IEEE754 floating point arithmetic
 3 * double precision: common utilities
 4 */
 5/*
 6 * MIPS floating point support
 7 * Copyright (C) 1994-2000 Algorithmics Ltd.
 8 */
 9
10#include "ieee754dp.h"
11
12int ieee754dp_tint(union ieee754dp x)
13{
14	u64 residue;
15	int round;
16	int sticky;
17	int odd;
18
19	COMPXDP;
20
21	ieee754_clearcx();
22
23	EXPLODEXDP;
24	FLUSHXDP;
25
26	switch (xc) {
27	case IEEE754_CLASS_SNAN:
28	case IEEE754_CLASS_QNAN:
29		ieee754_setcx(IEEE754_INVALID_OPERATION);
30		return ieee754si_indef();
31
32	case IEEE754_CLASS_INF:
33		ieee754_setcx(IEEE754_INVALID_OPERATION);
34		return ieee754si_overflow(xs);
35
36	case IEEE754_CLASS_ZERO:
37		return 0;
38
39	case IEEE754_CLASS_DNORM:
40	case IEEE754_CLASS_NORM:
41		break;
42	}
43	if (xe > 31) {
44		/* Set invalid. We will only use overflow for floating
45		   point overflow */
46		ieee754_setcx(IEEE754_INVALID_OPERATION);
47		return ieee754si_overflow(xs);
48	}
49	/* oh gawd */
50	if (xe > DP_FBITS) {
51		xm <<= xe - DP_FBITS;
52	} else if (xe < DP_FBITS) {
53		if (xe < -1) {
54			residue = xm;
55			round = 0;
56			sticky = residue != 0;
57			xm = 0;
58		} else {
59			residue = xm << (64 - DP_FBITS + xe);
60			round = (residue >> 63) != 0;
61			sticky = (residue << 1) != 0;
62			xm >>= DP_FBITS - xe;
63		}
64		/* Note: At this point upper 32 bits of xm are guaranteed
65		   to be zero */
66		odd = (xm & 0x1) != 0x0;
67		switch (ieee754_csr.rm) {
68		case FPU_CSR_RN:
69			if (round && (sticky || odd))
70				xm++;
71			break;
72		case FPU_CSR_RZ:
73			break;
74		case FPU_CSR_RU:	/* toward +Infinity */
75			if ((round || sticky) && !xs)
76				xm++;
77			break;
78		case FPU_CSR_RD:	/* toward -Infinity */
79			if ((round || sticky) && xs)
80				xm++;
81			break;
82		}
83		/* look for valid corner case 0x80000000 */
84		if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
85			/* This can happen after rounding */
86			ieee754_setcx(IEEE754_INVALID_OPERATION);
87			return ieee754si_overflow(xs);
88		}
89		if (round || sticky)
90			ieee754_setcx(IEEE754_INEXACT);
91	}
92	if (xs)
93		return -xm;
94	else
95		return xm;
96}
v6.8
 1// SPDX-License-Identifier: GPL-2.0-only
 2/* IEEE754 floating point arithmetic
 3 * double precision: common utilities
 4 */
 5/*
 6 * MIPS floating point support
 7 * Copyright (C) 1994-2000 Algorithmics Ltd.
 8 */
 9
10#include "ieee754dp.h"
11
12int ieee754dp_tint(union ieee754dp x)
13{
14	u64 residue;
15	int round;
16	int sticky;
17	int odd;
18
19	COMPXDP;
20
21	ieee754_clearcx();
22
23	EXPLODEXDP;
24	FLUSHXDP;
25
26	switch (xc) {
27	case IEEE754_CLASS_SNAN:
28	case IEEE754_CLASS_QNAN:
29		ieee754_setcx(IEEE754_INVALID_OPERATION);
30		return ieee754si_indef();
31
32	case IEEE754_CLASS_INF:
33		ieee754_setcx(IEEE754_INVALID_OPERATION);
34		return ieee754si_overflow(xs);
35
36	case IEEE754_CLASS_ZERO:
37		return 0;
38
39	case IEEE754_CLASS_DNORM:
40	case IEEE754_CLASS_NORM:
41		break;
42	}
43	if (xe > 31) {
44		/* Set invalid. We will only use overflow for floating
45		   point overflow */
46		ieee754_setcx(IEEE754_INVALID_OPERATION);
47		return ieee754si_overflow(xs);
48	}
49	/* oh gawd */
50	if (xe > DP_FBITS) {
51		xm <<= xe - DP_FBITS;
52	} else if (xe < DP_FBITS) {
53		if (xe < -1) {
54			residue = xm;
55			round = 0;
56			sticky = residue != 0;
57			xm = 0;
58		} else {
59			residue = xm << (64 - DP_FBITS + xe);
60			round = (residue >> 63) != 0;
61			sticky = (residue << 1) != 0;
62			xm >>= DP_FBITS - xe;
63		}
64		/* Note: At this point upper 32 bits of xm are guaranteed
65		   to be zero */
66		odd = (xm & 0x1) != 0x0;
67		switch (ieee754_csr.rm) {
68		case FPU_CSR_RN:
69			if (round && (sticky || odd))
70				xm++;
71			break;
72		case FPU_CSR_RZ:
73			break;
74		case FPU_CSR_RU:	/* toward +Infinity */
75			if ((round || sticky) && !xs)
76				xm++;
77			break;
78		case FPU_CSR_RD:	/* toward -Infinity */
79			if ((round || sticky) && xs)
80				xm++;
81			break;
82		}
83		/* look for valid corner case 0x80000000 */
84		if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
85			/* This can happen after rounding */
86			ieee754_setcx(IEEE754_INVALID_OPERATION);
87			return ieee754si_overflow(xs);
88		}
89		if (round || sticky)
90			ieee754_setcx(IEEE754_INEXACT);
91	}
92	if (xs)
93		return -xm;
94	else
95		return xm;
96}