diff options
Diffstat (limited to 'arch/mips/math-emu/dp_rint.c')
-rw-r--r-- | arch/mips/math-emu/dp_rint.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/arch/mips/math-emu/dp_rint.c b/arch/mips/math-emu/dp_rint.c new file mode 100644 index 000000000..7f30b7a30 --- /dev/null +++ b/arch/mips/math-emu/dp_rint.c | |||
@@ -0,0 +1,78 @@ | |||
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 | * Copyright (C) 2017 Imagination Technologies, Ltd. | ||
9 | * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com> | ||
10 | */ | ||
11 | |||
12 | #include "ieee754dp.h" | ||
13 | |||
14 | union ieee754dp ieee754dp_rint(union ieee754dp x) | ||
15 | { | ||
16 | union ieee754dp ret; | ||
17 | u64 residue; | ||
18 | int sticky; | ||
19 | int round; | ||
20 | int odd; | ||
21 | |||
22 | COMPXDP; | ||
23 | |||
24 | ieee754_clearcx(); | ||
25 | |||
26 | EXPLODEXDP; | ||
27 | FLUSHXDP; | ||
28 | |||
29 | if (xc == IEEE754_CLASS_SNAN) | ||
30 | return ieee754dp_nanxcpt(x); | ||
31 | |||
32 | if ((xc == IEEE754_CLASS_QNAN) || | ||
33 | (xc == IEEE754_CLASS_INF) || | ||
34 | (xc == IEEE754_CLASS_ZERO)) | ||
35 | return x; | ||
36 | |||
37 | if (xe >= DP_FBITS) | ||
38 | return x; | ||
39 | |||
40 | if (xe < -1) { | ||
41 | residue = xm; | ||
42 | round = 0; | ||
43 | sticky = residue != 0; | ||
44 | xm = 0; | ||
45 | } else { | ||
46 | residue = xm << (64 - DP_FBITS + xe); | ||
47 | round = (residue >> 63) != 0; | ||
48 | sticky = (residue << 1) != 0; | ||
49 | xm >>= DP_FBITS - xe; | ||
50 | } | ||
51 | |||
52 | odd = (xm & 0x1) != 0x0; | ||
53 | |||
54 | switch (ieee754_csr.rm) { | ||
55 | case FPU_CSR_RN: /* toward nearest */ | ||
56 | if (round && (sticky || odd)) | ||
57 | xm++; | ||
58 | break; | ||
59 | case FPU_CSR_RZ: /* toward zero */ | ||
60 | break; | ||
61 | case FPU_CSR_RU: /* toward +infinity */ | ||
62 | if ((round || sticky) && !xs) | ||
63 | xm++; | ||
64 | break; | ||
65 | case FPU_CSR_RD: /* toward -infinity */ | ||
66 | if ((round || sticky) && xs) | ||
67 | xm++; | ||
68 | break; | ||
69 | } | ||
70 | |||
71 | if (round || sticky) | ||
72 | ieee754_setcx(IEEE754_INEXACT); | ||
73 | |||
74 | ret = ieee754dp_flong(xm); | ||
75 | DPSIGN(ret) = xs; | ||
76 | |||
77 | return ret; | ||
78 | } | ||