0001
0002
0003
0004
0005
0006
0007
0008
0009
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;
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:
0057 if (round && (sticky || odd))
0058 xm++;
0059 break;
0060 case FPU_CSR_RZ:
0061 break;
0062 case FPU_CSR_RU:
0063 if ((round || sticky) && !xs)
0064 xm++;
0065 break;
0066 case FPU_CSR_RD:
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 }