Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* IEEE754 floating point arithmetic
0003  * single precision
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 "ieee754sp.h"
0013 
0014 union ieee754sp ieee754sp_rint(union ieee754sp x)
0015 {
0016     union ieee754sp ret;
0017     u32 residue;
0018     int sticky;
0019     int round;
0020     int odd;
0021 
0022     COMPXDP;        /* <-- DP needed for 64-bit mantissa tmp */
0023 
0024     ieee754_clearcx();
0025 
0026     EXPLODEXSP;
0027     FLUSHXSP;
0028 
0029     if (xc == IEEE754_CLASS_SNAN)
0030         return ieee754sp_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 >= SP_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 << (xe + 1);
0047         residue <<= 31 - SP_FBITS;
0048         round = (residue >> 31) != 0;
0049         sticky = (residue << 1) != 0;
0050         xm >>= SP_FBITS - xe;
0051     }
0052 
0053     odd = (xm & 0x1) != 0x0;
0054 
0055     switch (ieee754_csr.rm) {
0056     case FPU_CSR_RN:    /* toward nearest */
0057         if (round && (sticky || odd))
0058             xm++;
0059         break;
0060     case FPU_CSR_RZ:    /* toward zero */
0061         break;
0062     case FPU_CSR_RU:    /* toward +infinity */
0063         if ((round || sticky) && !xs)
0064             xm++;
0065         break;
0066     case FPU_CSR_RD:    /* toward -infinity */
0067         if ((round || sticky) && xs)
0068             xm++;
0069         break;
0070     }
0071 
0072     if (round || sticky)
0073         ieee754_setcx(IEEE754_INEXACT);
0074 
0075     ret = ieee754sp_flong(xm);
0076     SPSIGN(ret) = xs;
0077 
0078     return ret;
0079 }