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 } 80