1*f6cc69f1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 23ec404d8SAleksandar Markovic /* IEEE754 floating point arithmetic 33ec404d8SAleksandar Markovic * double precision: common utilities 43ec404d8SAleksandar Markovic */ 53ec404d8SAleksandar Markovic /* 63ec404d8SAleksandar Markovic * MIPS floating point support 73ec404d8SAleksandar Markovic * Copyright (C) 1994-2000 Algorithmics Ltd. 83ec404d8SAleksandar Markovic * Copyright (C) 2017 Imagination Technologies, Ltd. 93ec404d8SAleksandar Markovic * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com> 103ec404d8SAleksandar Markovic */ 113ec404d8SAleksandar Markovic 123ec404d8SAleksandar Markovic #include "ieee754dp.h" 133ec404d8SAleksandar Markovic ieee754dp_rint(union ieee754dp x)143ec404d8SAleksandar Markovicunion ieee754dp ieee754dp_rint(union ieee754dp x) 153ec404d8SAleksandar Markovic { 163ec404d8SAleksandar Markovic union ieee754dp ret; 173ec404d8SAleksandar Markovic u64 residue; 183ec404d8SAleksandar Markovic int sticky; 193ec404d8SAleksandar Markovic int round; 203ec404d8SAleksandar Markovic int odd; 213ec404d8SAleksandar Markovic 223ec404d8SAleksandar Markovic COMPXDP; 233ec404d8SAleksandar Markovic 243ec404d8SAleksandar Markovic ieee754_clearcx(); 253ec404d8SAleksandar Markovic 263ec404d8SAleksandar Markovic EXPLODEXDP; 273ec404d8SAleksandar Markovic FLUSHXDP; 283ec404d8SAleksandar Markovic 293ec404d8SAleksandar Markovic if (xc == IEEE754_CLASS_SNAN) 303ec404d8SAleksandar Markovic return ieee754dp_nanxcpt(x); 313ec404d8SAleksandar Markovic 323ec404d8SAleksandar Markovic if ((xc == IEEE754_CLASS_QNAN) || 333ec404d8SAleksandar Markovic (xc == IEEE754_CLASS_INF) || 343ec404d8SAleksandar Markovic (xc == IEEE754_CLASS_ZERO)) 353ec404d8SAleksandar Markovic return x; 363ec404d8SAleksandar Markovic 373ec404d8SAleksandar Markovic if (xe >= DP_FBITS) 383ec404d8SAleksandar Markovic return x; 393ec404d8SAleksandar Markovic 403ec404d8SAleksandar Markovic if (xe < -1) { 413ec404d8SAleksandar Markovic residue = xm; 423ec404d8SAleksandar Markovic round = 0; 433ec404d8SAleksandar Markovic sticky = residue != 0; 443ec404d8SAleksandar Markovic xm = 0; 453ec404d8SAleksandar Markovic } else { 463ec404d8SAleksandar Markovic residue = xm << (64 - DP_FBITS + xe); 473ec404d8SAleksandar Markovic round = (residue >> 63) != 0; 483ec404d8SAleksandar Markovic sticky = (residue << 1) != 0; 493ec404d8SAleksandar Markovic xm >>= DP_FBITS - xe; 503ec404d8SAleksandar Markovic } 513ec404d8SAleksandar Markovic 523ec404d8SAleksandar Markovic odd = (xm & 0x1) != 0x0; 533ec404d8SAleksandar Markovic 543ec404d8SAleksandar Markovic switch (ieee754_csr.rm) { 553ec404d8SAleksandar Markovic case FPU_CSR_RN: /* toward nearest */ 563ec404d8SAleksandar Markovic if (round && (sticky || odd)) 573ec404d8SAleksandar Markovic xm++; 583ec404d8SAleksandar Markovic break; 593ec404d8SAleksandar Markovic case FPU_CSR_RZ: /* toward zero */ 603ec404d8SAleksandar Markovic break; 613ec404d8SAleksandar Markovic case FPU_CSR_RU: /* toward +infinity */ 623ec404d8SAleksandar Markovic if ((round || sticky) && !xs) 633ec404d8SAleksandar Markovic xm++; 643ec404d8SAleksandar Markovic break; 653ec404d8SAleksandar Markovic case FPU_CSR_RD: /* toward -infinity */ 663ec404d8SAleksandar Markovic if ((round || sticky) && xs) 673ec404d8SAleksandar Markovic xm++; 683ec404d8SAleksandar Markovic break; 693ec404d8SAleksandar Markovic } 703ec404d8SAleksandar Markovic 713ec404d8SAleksandar Markovic if (round || sticky) 723ec404d8SAleksandar Markovic ieee754_setcx(IEEE754_INEXACT); 733ec404d8SAleksandar Markovic 743ec404d8SAleksandar Markovic ret = ieee754dp_flong(xm); 753ec404d8SAleksandar Markovic DPSIGN(ret) = xs; 763ec404d8SAleksandar Markovic 773ec404d8SAleksandar Markovic return ret; 783ec404d8SAleksandar Markovic } 79