Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* IEEE754 floating point arithmetic
0003  * double precision: common utilities
0004  */
0005 /*
0006  * MIPS floating point support
0007  * Copyright (C) 1994-2000 Algorithmics Ltd.
0008  * Copyright (C) 2017 Imagination Technologies, Ltd.
0009  * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
0010  */
0011 
0012 #include "ieee754dp.h"
0013 
0014 union ieee754dp ieee754dp_rint(union ieee754dp x)
0015 {
0016     union ieee754dp ret;
0017     u64 residue;
0018     int sticky;
0019     int round;
0020     int odd;
0021 
0022     COMPXDP;
0023 
0024     ieee754_clearcx();
0025 
0026     EXPLODEXDP;
0027     FLUSHXDP;
0028 
0029     if (xc == IEEE754_CLASS_SNAN)
0030         return ieee754dp_nanxcpt(x);
0031 
0032     if ((xc == IEEE754_CLASS_QNAN) ||
0033         (xc == IEEE754_CLASS_INF) ||
0034         (xc == IEEE754_CLASS_ZERO))
0035         return x;
0036 
0037     if (xe >= DP_FBITS)
0038         return x;
0039 
0040     if (xe < -1) {
0041         residue = xm;
0042         round = 0;
0043         sticky = residue != 0;
0044         xm = 0;
0045     } else {
0046         residue = xm << (64 - DP_FBITS + xe);
0047         round = (residue >> 63) != 0;
0048         sticky = (residue << 1) != 0;
0049         xm >>= DP_FBITS - xe;
0050     }
0051 
0052     odd = (xm & 0x1) != 0x0;
0053 
0054     switch (ieee754_csr.rm) {
0055     case FPU_CSR_RN:    /* toward nearest */
0056         if (round && (sticky || odd))
0057             xm++;
0058         break;
0059     case FPU_CSR_RZ:    /* toward zero */
0060         break;
0061     case FPU_CSR_RU:    /* toward +infinity */
0062         if ((round || sticky) && !xs)
0063             xm++;
0064         break;
0065     case FPU_CSR_RD:    /* toward -infinity */
0066         if ((round || sticky) && xs)
0067             xm++;
0068         break;
0069     }
0070 
0071     if (round || sticky)
0072         ieee754_setcx(IEEE754_INEXACT);
0073 
0074     ret = ieee754dp_flong(xm);
0075     DPSIGN(ret) = xs;
0076 
0077     return ret;
0078 }