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_add.c (3825B)


      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 */
      9
     10#include "ieee754dp.h"
     11
     12union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
     13{
     14	int s;
     15
     16	COMPXDP;
     17	COMPYDP;
     18
     19	EXPLODEXDP;
     20	EXPLODEYDP;
     21
     22	ieee754_clearcx();
     23
     24	FLUSHXDP;
     25	FLUSHYDP;
     26
     27	switch (CLPAIR(xc, yc)) {
     28	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
     29	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
     30	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
     31	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
     32	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
     33		return ieee754dp_nanxcpt(y);
     34
     35	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
     36	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
     37	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
     38	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
     39	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
     40	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
     41		return ieee754dp_nanxcpt(x);
     42
     43	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
     44	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
     45	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
     46	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
     47		return y;
     48
     49	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
     50	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
     51	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
     52	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
     53	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
     54		return x;
     55
     56
     57	/*
     58	 * Infinity handling
     59	 */
     60	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
     61		if (xs == ys)
     62			return x;
     63		ieee754_setcx(IEEE754_INVALID_OPERATION);
     64		return ieee754dp_indef();
     65
     66	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
     67	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
     68	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
     69		return y;
     70
     71	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
     72	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
     73	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
     74		return x;
     75
     76	/*
     77	 * Zero handling
     78	 */
     79	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
     80		if (xs == ys)
     81			return x;
     82		else
     83			return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
     84
     85	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
     86	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
     87		return x;
     88
     89	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
     90	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
     91		return y;
     92
     93	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
     94		DPDNORMX;
     95		fallthrough;
     96	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
     97		DPDNORMY;
     98		break;
     99
    100	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
    101		DPDNORMX;
    102		break;
    103
    104	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
    105		break;
    106	}
    107	assert(xm & DP_HIDDEN_BIT);
    108	assert(ym & DP_HIDDEN_BIT);
    109
    110	/*
    111	 * Provide guard,round and stick bit space.
    112	 */
    113	xm <<= 3;
    114	ym <<= 3;
    115
    116	if (xe > ye) {
    117		/*
    118		 * Have to shift y fraction right to align.
    119		 */
    120		s = xe - ye;
    121		ym = XDPSRS(ym, s);
    122		ye += s;
    123	} else if (ye > xe) {
    124		/*
    125		 * Have to shift x fraction right to align.
    126		 */
    127		s = ye - xe;
    128		xm = XDPSRS(xm, s);
    129		xe += s;
    130	}
    131	assert(xe == ye);
    132	assert(xe <= DP_EMAX);
    133
    134	if (xs == ys) {
    135		/*
    136		 * Generate 28 bit result of adding two 27 bit numbers
    137		 * leaving result in xm, xs and xe.
    138		 */
    139		xm = xm + ym;
    140
    141		if (xm >> (DP_FBITS + 1 + 3)) { /* carry out */
    142			xm = XDPSRS1(xm);
    143			xe++;
    144		}
    145	} else {
    146		if (xm >= ym) {
    147			xm = xm - ym;
    148		} else {
    149			xm = ym - xm;
    150			xs = ys;
    151		}
    152		if (xm == 0)
    153			return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
    154
    155		/*
    156		 * Normalize to rounding precision.
    157		 */
    158		while ((xm >> (DP_FBITS + 3)) == 0) {
    159			xm <<= 1;
    160			xe--;
    161		}
    162	}
    163
    164	return ieee754dp_format(xs, xe, xm);
    165}