cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dp_rint.c (1453B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* IEEE754 floating point arithmetic
      3 * double precision: common utilities
      4 */
      5/*
      6 * MIPS floating point support
      7 * Copyright (C) 1994-2000 Algorithmics Ltd.
      8 * Copyright (C) 2017 Imagination Technologies, Ltd.
      9 * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
     10 */
     11
     12#include "ieee754dp.h"
     13
     14union ieee754dp ieee754dp_rint(union ieee754dp x)
     15{
     16	union ieee754dp ret;
     17	u64 residue;
     18	int sticky;
     19	int round;
     20	int odd;
     21
     22	COMPXDP;
     23
     24	ieee754_clearcx();
     25
     26	EXPLODEXDP;
     27	FLUSHXDP;
     28
     29	if (xc == IEEE754_CLASS_SNAN)
     30		return ieee754dp_nanxcpt(x);
     31
     32	if ((xc == IEEE754_CLASS_QNAN) ||
     33	    (xc == IEEE754_CLASS_INF) ||
     34	    (xc == IEEE754_CLASS_ZERO))
     35		return x;
     36
     37	if (xe >= DP_FBITS)
     38		return x;
     39
     40	if (xe < -1) {
     41		residue = xm;
     42		round = 0;
     43		sticky = residue != 0;
     44		xm = 0;
     45	} else {
     46		residue = xm << (64 - DP_FBITS + xe);
     47		round = (residue >> 63) != 0;
     48		sticky = (residue << 1) != 0;
     49		xm >>= DP_FBITS - xe;
     50	}
     51
     52	odd = (xm & 0x1) != 0x0;
     53
     54	switch (ieee754_csr.rm) {
     55	case FPU_CSR_RN:	/* toward nearest */
     56		if (round && (sticky || odd))
     57			xm++;
     58		break;
     59	case FPU_CSR_RZ:	/* toward zero */
     60		break;
     61	case FPU_CSR_RU:	/* toward +infinity */
     62		if ((round || sticky) && !xs)
     63			xm++;
     64		break;
     65	case FPU_CSR_RD:	/* toward -infinity */
     66		if ((round || sticky) && xs)
     67			xm++;
     68		break;
     69	}
     70
     71	if (round || sticky)
     72		ieee754_setcx(IEEE754_INEXACT);
     73
     74	ret = ieee754dp_flong(xm);
     75	DPSIGN(ret) = xs;
     76
     77	return ret;
     78}