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