Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
 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 * Copyright (C) 2017 Imagination Technologies, Ltd.
 8 * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
 9 *
10 *  This program is free software; you can distribute it and/or modify it
11 *  under the terms of the GNU General Public License (Version 2) as
12 *  published by the Free Software Foundation.
13 *
14 *  This program is distributed in the hope it will be useful, but WITHOUT
15 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 *  for more details.
18 *
19 *  You should have received a copy of the GNU General Public License along
20 *  with this program.
21 */
22
23#include "ieee754dp.h"
24
25union ieee754dp ieee754dp_rint(union ieee754dp x)
26{
27	union ieee754dp ret;
28	u64 residue;
29	int sticky;
30	int round;
31	int odd;
32
33	COMPXDP;
34
35	ieee754_clearcx();
36
37	EXPLODEXDP;
38	FLUSHXDP;
39
40	if (xc == IEEE754_CLASS_SNAN)
41		return ieee754dp_nanxcpt(x);
42
43	if ((xc == IEEE754_CLASS_QNAN) ||
44	    (xc == IEEE754_CLASS_INF) ||
45	    (xc == IEEE754_CLASS_ZERO))
46		return x;
47
48	if (xe >= DP_FBITS)
49		return x;
50
51	if (xe < -1) {
52		residue = xm;
53		round = 0;
54		sticky = residue != 0;
55		xm = 0;
56	} else {
57		residue = xm << (64 - DP_FBITS + xe);
58		round = (residue >> 63) != 0;
59		sticky = (residue << 1) != 0;
60		xm >>= DP_FBITS - xe;
61	}
62
63	odd = (xm & 0x1) != 0x0;
64
65	switch (ieee754_csr.rm) {
66	case FPU_CSR_RN:	/* toward nearest */
67		if (round && (sticky || odd))
68			xm++;
69		break;
70	case FPU_CSR_RZ:	/* toward zero */
71		break;
72	case FPU_CSR_RU:	/* toward +infinity */
73		if ((round || sticky) && !xs)
74			xm++;
75		break;
76	case FPU_CSR_RD:	/* toward -infinity */
77		if ((round || sticky) && xs)
78			xm++;
79		break;
80	}
81
82	if (round || sticky)
83		ieee754_setcx(IEEE754_INEXACT);
84
85	ret = ieee754dp_flong(xm);
86	DPSIGN(ret) = xs;
87
88	return ret;
89}