13ec404d8SAleksandar Markovic /* IEEE754 floating point arithmetic 23ec404d8SAleksandar Markovic * double precision: common utilities 33ec404d8SAleksandar Markovic */ 43ec404d8SAleksandar Markovic /* 53ec404d8SAleksandar Markovic * MIPS floating point support 63ec404d8SAleksandar Markovic * Copyright (C) 1994-2000 Algorithmics Ltd. 73ec404d8SAleksandar Markovic * Copyright (C) 2017 Imagination Technologies, Ltd. 83ec404d8SAleksandar Markovic * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com> 93ec404d8SAleksandar Markovic * 103ec404d8SAleksandar Markovic * This program is free software; you can distribute it and/or modify it 113ec404d8SAleksandar Markovic * under the terms of the GNU General Public License (Version 2) as 123ec404d8SAleksandar Markovic * published by the Free Software Foundation. 133ec404d8SAleksandar Markovic * 143ec404d8SAleksandar Markovic * This program is distributed in the hope it will be useful, but WITHOUT 153ec404d8SAleksandar Markovic * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 163ec404d8SAleksandar Markovic * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 173ec404d8SAleksandar Markovic * for more details. 183ec404d8SAleksandar Markovic * 193ec404d8SAleksandar Markovic * You should have received a copy of the GNU General Public License along 203ec404d8SAleksandar Markovic * with this program. 213ec404d8SAleksandar Markovic */ 223ec404d8SAleksandar Markovic 233ec404d8SAleksandar Markovic #include "ieee754dp.h" 243ec404d8SAleksandar Markovic 253ec404d8SAleksandar Markovic union ieee754dp ieee754dp_rint(union ieee754dp x) 263ec404d8SAleksandar Markovic { 273ec404d8SAleksandar Markovic union ieee754dp ret; 283ec404d8SAleksandar Markovic u64 residue; 293ec404d8SAleksandar Markovic int sticky; 303ec404d8SAleksandar Markovic int round; 313ec404d8SAleksandar Markovic int odd; 323ec404d8SAleksandar Markovic 333ec404d8SAleksandar Markovic COMPXDP; 343ec404d8SAleksandar Markovic 353ec404d8SAleksandar Markovic ieee754_clearcx(); 363ec404d8SAleksandar Markovic 373ec404d8SAleksandar Markovic EXPLODEXDP; 383ec404d8SAleksandar Markovic FLUSHXDP; 393ec404d8SAleksandar Markovic 403ec404d8SAleksandar Markovic if (xc == IEEE754_CLASS_SNAN) 413ec404d8SAleksandar Markovic return ieee754dp_nanxcpt(x); 423ec404d8SAleksandar Markovic 433ec404d8SAleksandar Markovic if ((xc == IEEE754_CLASS_QNAN) || 443ec404d8SAleksandar Markovic (xc == IEEE754_CLASS_INF) || 453ec404d8SAleksandar Markovic (xc == IEEE754_CLASS_ZERO)) 463ec404d8SAleksandar Markovic return x; 473ec404d8SAleksandar Markovic 483ec404d8SAleksandar Markovic if (xe >= DP_FBITS) 493ec404d8SAleksandar Markovic return x; 503ec404d8SAleksandar Markovic 513ec404d8SAleksandar Markovic if (xe < -1) { 523ec404d8SAleksandar Markovic residue = xm; 533ec404d8SAleksandar Markovic round = 0; 543ec404d8SAleksandar Markovic sticky = residue != 0; 553ec404d8SAleksandar Markovic xm = 0; 563ec404d8SAleksandar Markovic } else { 573ec404d8SAleksandar Markovic residue = xm << (64 - DP_FBITS + xe); 583ec404d8SAleksandar Markovic round = (residue >> 63) != 0; 593ec404d8SAleksandar Markovic sticky = (residue << 1) != 0; 603ec404d8SAleksandar Markovic xm >>= DP_FBITS - xe; 613ec404d8SAleksandar Markovic } 623ec404d8SAleksandar Markovic 633ec404d8SAleksandar Markovic odd = (xm & 0x1) != 0x0; 643ec404d8SAleksandar Markovic 653ec404d8SAleksandar Markovic switch (ieee754_csr.rm) { 663ec404d8SAleksandar Markovic case FPU_CSR_RN: /* toward nearest */ 673ec404d8SAleksandar Markovic if (round && (sticky || odd)) 683ec404d8SAleksandar Markovic xm++; 693ec404d8SAleksandar Markovic break; 703ec404d8SAleksandar Markovic case FPU_CSR_RZ: /* toward zero */ 713ec404d8SAleksandar Markovic break; 723ec404d8SAleksandar Markovic case FPU_CSR_RU: /* toward +infinity */ 733ec404d8SAleksandar Markovic if ((round || sticky) && !xs) 743ec404d8SAleksandar Markovic xm++; 753ec404d8SAleksandar Markovic break; 763ec404d8SAleksandar Markovic case FPU_CSR_RD: /* toward -infinity */ 773ec404d8SAleksandar Markovic if ((round || sticky) && xs) 783ec404d8SAleksandar Markovic xm++; 793ec404d8SAleksandar Markovic break; 803ec404d8SAleksandar Markovic } 813ec404d8SAleksandar Markovic 823ec404d8SAleksandar Markovic if (round || sticky) 833ec404d8SAleksandar Markovic ieee754_setcx(IEEE754_INEXACT); 843ec404d8SAleksandar Markovic 853ec404d8SAleksandar Markovic ret = ieee754dp_flong(xm); 863ec404d8SAleksandar Markovic DPSIGN(ret) = xs; 873ec404d8SAleksandar Markovic 883ec404d8SAleksandar Markovic return ret; 893ec404d8SAleksandar Markovic } 90