Linux Audio

Check our new training course

Loading...
v4.6
 
  1/* IEEE754 floating point arithmetic
  2 * double precision: common utilities
  3 */
  4/*
  5 * MIPS floating point support
  6 * Copyright (C) 1994-2000 Algorithmics Ltd.
  7 *
  8 *  This program is free software; you can distribute it and/or modify it
  9 *  under the terms of the GNU General Public License (Version 2) as
 10 *  published by the Free Software Foundation.
 11 *
 12 *  This program is distributed in the hope it will be useful, but WITHOUT
 13 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 14 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 15 *  for more details.
 16 *
 17 *  You should have received a copy of the GNU General Public License along
 18 *  with this program; if not, write to the Free Software Foundation, Inc.,
 19 *  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 20 */
 21
 22#include "ieee754dp.h"
 23
 24int ieee754dp_tint(union ieee754dp x)
 25{
 26	u64 residue;
 27	int round;
 28	int sticky;
 29	int odd;
 30
 31	COMPXDP;
 32
 33	ieee754_clearcx();
 34
 35	EXPLODEXDP;
 36	FLUSHXDP;
 37
 38	switch (xc) {
 39	case IEEE754_CLASS_SNAN:
 40	case IEEE754_CLASS_QNAN:
 41		ieee754_setcx(IEEE754_INVALID_OPERATION);
 42		return ieee754si_indef();
 43
 44	case IEEE754_CLASS_INF:
 45		ieee754_setcx(IEEE754_INVALID_OPERATION);
 46		return ieee754si_overflow(xs);
 47
 48	case IEEE754_CLASS_ZERO:
 49		return 0;
 50
 51	case IEEE754_CLASS_DNORM:
 52	case IEEE754_CLASS_NORM:
 53		break;
 54	}
 55	if (xe > 31) {
 56		/* Set invalid. We will only use overflow for floating
 57		   point overflow */
 58		ieee754_setcx(IEEE754_INVALID_OPERATION);
 59		return ieee754si_overflow(xs);
 60	}
 61	/* oh gawd */
 62	if (xe > DP_FBITS) {
 63		xm <<= xe - DP_FBITS;
 64	} else if (xe < DP_FBITS) {
 65		if (xe < -1) {
 66			residue = xm;
 67			round = 0;
 68			sticky = residue != 0;
 69			xm = 0;
 70		} else {
 71			residue = xm << (64 - DP_FBITS + xe);
 72			round = (residue >> 63) != 0;
 73			sticky = (residue << 1) != 0;
 74			xm >>= DP_FBITS - xe;
 75		}
 76		/* Note: At this point upper 32 bits of xm are guaranteed
 77		   to be zero */
 78		odd = (xm & 0x1) != 0x0;
 79		switch (ieee754_csr.rm) {
 80		case FPU_CSR_RN:
 81			if (round && (sticky || odd))
 82				xm++;
 83			break;
 84		case FPU_CSR_RZ:
 85			break;
 86		case FPU_CSR_RU:	/* toward +Infinity */
 87			if ((round || sticky) && !xs)
 88				xm++;
 89			break;
 90		case FPU_CSR_RD:	/* toward -Infinity */
 91			if ((round || sticky) && xs)
 92				xm++;
 93			break;
 94		}
 95		/* look for valid corner case 0x80000000 */
 96		if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
 97			/* This can happen after rounding */
 98			ieee754_setcx(IEEE754_INVALID_OPERATION);
 99			return ieee754si_overflow(xs);
100		}
101		if (round || sticky)
102			ieee754_setcx(IEEE754_INEXACT);
103	}
104	if (xs)
105		return -xm;
106	else
107		return xm;
108}
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}