diff options
Diffstat (limited to 'arch/mips/math-emu/sp_rint.c')
-rw-r--r-- | arch/mips/math-emu/sp_rint.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/arch/mips/math-emu/sp_rint.c b/arch/mips/math-emu/sp_rint.c new file mode 100644 index 000000000..d5f75fe21 --- /dev/null +++ b/arch/mips/math-emu/sp_rint.c | |||
@@ -0,0 +1,79 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /* IEEE754 floating point arithmetic | ||
3 | * single precision | ||
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 "ieee754sp.h" | ||
13 | |||
14 | union ieee754sp ieee754sp_rint(union ieee754sp x) | ||
15 | { | ||
16 | union ieee754sp ret; | ||
17 | u32 residue; | ||
18 | int sticky; | ||
19 | int round; | ||
20 | int odd; | ||
21 | |||
22 | COMPXDP; /* <-- DP needed for 64-bit mantissa tmp */ | ||
23 | |||
24 | ieee754_clearcx(); | ||
25 | |||
26 | EXPLODEXSP; | ||
27 | FLUSHXSP; | ||
28 | |||
29 | if (xc == IEEE754_CLASS_SNAN) | ||
30 | return ieee754sp_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 >= SP_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 << (xe + 1); | ||
47 | residue <<= 31 - SP_FBITS; | ||
48 | round = (residue >> 31) != 0; | ||
49 | sticky = (residue << 1) != 0; | ||
50 | xm >>= SP_FBITS - xe; | ||
51 | } | ||
52 | |||
53 | odd = (xm & 0x1) != 0x0; | ||
54 | |||
55 | switch (ieee754_csr.rm) { | ||
56 | case FPU_CSR_RN: /* toward nearest */ | ||
57 | if (round && (sticky || odd)) | ||
58 | xm++; | ||
59 | break; | ||
60 | case FPU_CSR_RZ: /* toward zero */ | ||
61 | break; | ||
62 | case FPU_CSR_RU: /* toward +infinity */ | ||
63 | if ((round || sticky) && !xs) | ||
64 | xm++; | ||
65 | break; | ||
66 | case FPU_CSR_RD: /* toward -infinity */ | ||
67 | if ((round || sticky) && xs) | ||
68 | xm++; | ||
69 | break; | ||
70 | } | ||
71 | |||
72 | if (round || sticky) | ||
73 | ieee754_setcx(IEEE754_INEXACT); | ||
74 | |||
75 | ret = ieee754sp_flong(xm); | ||
76 | SPSIGN(ret) = xs; | ||
77 | |||
78 | return ret; | ||
79 | } | ||