]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - arch/mips/math-emu/sp_tlong.c
Merge tag 'gpio-v5.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux...
[mirror_ubuntu-jammy-kernel.git] / arch / mips / math-emu / sp_tlong.c
CommitLineData
9d5a6349 1// SPDX-License-Identifier: GPL-2.0-only
1da177e4
LT
2/* IEEE754 floating point arithmetic
3 * single precision
4 */
5/*
6 * MIPS floating point support
7 * Copyright (C) 1994-2000 Algorithmics Ltd.
1da177e4
LT
8 */
9
1da177e4
LT
10#include "ieee754sp.h"
11
2209bcb1 12s64 ieee754sp_tlong(union ieee754sp x)
1da177e4 13{
3f7cac41
RB
14 u32 residue;
15 int round;
16 int sticky;
17 int odd;
18
1da177e4
LT
19 COMPXDP; /* <-- need 64-bit mantissa tmp */
20
9e8bad1f 21 ieee754_clearcx();
1da177e4
LT
22
23 EXPLODEXSP;
24 FLUSHXSP;
25
26 switch (xc) {
27 case IEEE754_CLASS_SNAN:
28 case IEEE754_CLASS_QNAN:
9e8bad1f 29 ieee754_setcx(IEEE754_INVALID_OPERATION);
90efba36 30 return ieee754di_indef();
3f7cac41 31
90d53a91
MR
32 case IEEE754_CLASS_INF:
33 ieee754_setcx(IEEE754_INVALID_OPERATION);
34 return ieee754di_overflow(xs);
35
1da177e4
LT
36 case IEEE754_CLASS_ZERO:
37 return 0;
3f7cac41 38
1da177e4
LT
39 case IEEE754_CLASS_DNORM:
40 case IEEE754_CLASS_NORM:
41 break;
42 }
43 if (xe >= 63) {
44 /* look for valid corner case */
45 if (xe == 63 && xs && xm == SP_HIDDEN_BIT)
46 return -0x8000000000000000LL;
47 /* Set invalid. We will only use overflow for floating
48 point overflow */
9e8bad1f 49 ieee754_setcx(IEEE754_INVALID_OPERATION);
90d53a91 50 return ieee754di_overflow(xs);
1da177e4
LT
51 }
52 /* oh gawd */
ad8fb553
RB
53 if (xe > SP_FBITS) {
54 xm <<= xe - SP_FBITS;
55 } else if (xe < SP_FBITS) {
1da177e4
LT
56 if (xe < -1) {
57 residue = xm;
58 round = 0;
59 sticky = residue != 0;
60 xm = 0;
abb86dc5 61 } else {
ad8fb553 62 residue = xm << (32 - SP_FBITS + xe);
1da177e4
LT
63 round = (residue >> 31) != 0;
64 sticky = (residue << 1) != 0;
ad8fb553 65 xm >>= SP_FBITS - xe;
1da177e4
LT
66 }
67 odd = (xm & 0x1) != 0x0;
68 switch (ieee754_csr.rm) {
56a64733 69 case FPU_CSR_RN:
1da177e4
LT
70 if (round && (sticky || odd))
71 xm++;
72 break;
56a64733 73 case FPU_CSR_RZ:
1da177e4 74 break;
56a64733 75 case FPU_CSR_RU: /* toward +Infinity */
1da177e4
LT
76 if ((round || sticky) && !xs)
77 xm++;
78 break;
56a64733 79 case FPU_CSR_RD: /* toward -Infinity */
1da177e4
LT
80 if ((round || sticky) && xs)
81 xm++;
82 break;
83 }
84 if ((xm >> 63) != 0) {
85 /* This can happen after rounding */
9e8bad1f 86 ieee754_setcx(IEEE754_INVALID_OPERATION);
90d53a91 87 return ieee754di_overflow(xs);
1da177e4
LT
88 }
89 if (round || sticky)
9e8bad1f 90 ieee754_setcx(IEEE754_INEXACT);
1da177e4
LT
91 }
92 if (xs)
93 return -xm;
94 else
95 return xm;
96}