1 /* IEEE754 floating point arithmetic 2 * single precision 3 */ 4 /* 5 * MIPS floating point support 6 * Copyright (C) 1994-2000 Algorithmics Ltd. 7 * Copyright (C) 2017 Imagination Technologies, Ltd. 8 * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com> 9 * 10 * This program is free software; you can distribute it and/or modify it 11 * under the terms of the GNU General Public License (Version 2) as 12 * published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope it will be useful, but WITHOUT 15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 * for more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program. 21 */ 22 23 #include "ieee754sp.h" 24 25 union ieee754sp ieee754sp_rint(union ieee754sp x) 26 { 27 union ieee754sp ret; 28 u32 residue; 29 int sticky; 30 int round; 31 int odd; 32 33 COMPXDP; /* <-- DP needed for 64-bit mantissa tmp */ 34 35 ieee754_clearcx(); 36 37 EXPLODEXSP; 38 FLUSHXSP; 39 40 if (xc == IEEE754_CLASS_SNAN) 41 return ieee754sp_nanxcpt(x); 42 43 if ((xc == IEEE754_CLASS_QNAN) || 44 (xc == IEEE754_CLASS_INF) || 45 (xc == IEEE754_CLASS_ZERO)) 46 return x; 47 48 if (xe >= SP_FBITS) 49 return x; 50 51 if (xe < -1) { 52 residue = xm; 53 round = 0; 54 sticky = residue != 0; 55 xm = 0; 56 } else { 57 residue = xm << (xe + 1); 58 residue <<= 31 - SP_FBITS; 59 round = (residue >> 31) != 0; 60 sticky = (residue << 1) != 0; 61 xm >>= SP_FBITS - xe; 62 } 63 64 odd = (xm & 0x1) != 0x0; 65 66 switch (ieee754_csr.rm) { 67 case FPU_CSR_RN: /* toward nearest */ 68 if (round && (sticky || odd)) 69 xm++; 70 break; 71 case FPU_CSR_RZ: /* toward zero */ 72 break; 73 case FPU_CSR_RU: /* toward +infinity */ 74 if ((round || sticky) && !xs) 75 xm++; 76 break; 77 case FPU_CSR_RD: /* toward -infinity */ 78 if ((round || sticky) && xs) 79 xm++; 80 break; 81 } 82 83 if (round || sticky) 84 ieee754_setcx(IEEE754_INEXACT); 85 86 ret = ieee754sp_flong(xm); 87 SPSIGN(ret) = xs; 88 89 return ret; 90 } 91