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