summaryrefslogtreecommitdiffstats
path: root/arch/mips/math-emu/sp_rint.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 10:05:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 10:05:51 +0000
commit5d1646d90e1f2cceb9f0828f4b28318cd0ec7744 (patch)
treea94efe259b9009378be6d90eb30d2b019d95c194 /arch/mips/math-emu/sp_rint.c
parentInitial commit. (diff)
downloadlinux-5d1646d90e1f2cceb9f0828f4b28318cd0ec7744.tar.xz
linux-5d1646d90e1f2cceb9f0828f4b28318cd0ec7744.zip
Adding upstream version 5.10.209.upstream/5.10.209
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'arch/mips/math-emu/sp_rint.c')
-rw-r--r--arch/mips/math-emu/sp_rint.c79
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 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* IEEE754 floating point arithmetic
+ * single precision
+ */
+/*
+ * MIPS floating point support
+ * Copyright (C) 1994-2000 Algorithmics Ltd.
+ * Copyright (C) 2017 Imagination Technologies, Ltd.
+ * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+ */
+
+#include "ieee754sp.h"
+
+union ieee754sp ieee754sp_rint(union ieee754sp x)
+{
+ union ieee754sp ret;
+ u32 residue;
+ int sticky;
+ int round;
+ int odd;
+
+ COMPXDP; /* <-- DP needed for 64-bit mantissa tmp */
+
+ ieee754_clearcx();
+
+ EXPLODEXSP;
+ FLUSHXSP;
+
+ if (xc == IEEE754_CLASS_SNAN)
+ return ieee754sp_nanxcpt(x);
+
+ if ((xc == IEEE754_CLASS_QNAN) ||
+ (xc == IEEE754_CLASS_INF) ||
+ (xc == IEEE754_CLASS_ZERO))
+ return x;
+
+ if (xe >= SP_FBITS)
+ return x;
+
+ if (xe < -1) {
+ residue = xm;
+ round = 0;
+ sticky = residue != 0;
+ xm = 0;
+ } else {
+ residue = xm << (xe + 1);
+ residue <<= 31 - SP_FBITS;
+ round = (residue >> 31) != 0;
+ sticky = (residue << 1) != 0;
+ xm >>= SP_FBITS - xe;
+ }
+
+ odd = (xm & 0x1) != 0x0;
+
+ switch (ieee754_csr.rm) {
+ case FPU_CSR_RN: /* toward nearest */
+ if (round && (sticky || odd))
+ xm++;
+ break;
+ case FPU_CSR_RZ: /* toward zero */
+ break;
+ case FPU_CSR_RU: /* toward +infinity */
+ if ((round || sticky) && !xs)
+ xm++;
+ break;
+ case FPU_CSR_RD: /* toward -infinity */
+ if ((round || sticky) && xs)
+ xm++;
+ break;
+ }
+
+ if (round || sticky)
+ ieee754_setcx(IEEE754_INEXACT);
+
+ ret = ieee754sp_flong(xm);
+ SPSIGN(ret) = xs;
+
+ return ret;
+}