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