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_sub.c (4088B)


      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_sub(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_ZERO, IEEE754_CLASS_INF):
     67	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
     68	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
     69		return ieee754dp_inf(ys ^ 1);
     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		/* quick fix up */
     92		DPSIGN(y) ^= 1;
     93		return y;
     94
     95	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
     96		DPDNORMX;
     97		fallthrough;
     98	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
     99		/* normalize ym,ye */
    100		DPDNORMY;
    101		break;
    102
    103	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
    104		/* normalize xm,xe */
    105		DPDNORMX;
    106		break;
    107
    108	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
    109		break;
    110	}
    111	/* flip sign of y and handle as add */
    112	ys ^= 1;
    113
    114	assert(xm & DP_HIDDEN_BIT);
    115	assert(ym & DP_HIDDEN_BIT);
    116
    117
    118	/* provide guard,round and stick bit dpace */
    119	xm <<= 3;
    120	ym <<= 3;
    121
    122	if (xe > ye) {
    123		/*
    124		 * Have to shift y fraction right to align
    125		 */
    126		s = xe - ye;
    127		ym = XDPSRS(ym, s);
    128		ye += s;
    129	} else if (ye > xe) {
    130		/*
    131		 * Have to shift x fraction right to align
    132		 */
    133		s = ye - xe;
    134		xm = XDPSRS(xm, s);
    135		xe += s;
    136	}
    137	assert(xe == ye);
    138	assert(xe <= DP_EMAX);
    139
    140	if (xs == ys) {
    141		/* generate 28 bit result of adding two 27 bit numbers
    142		 */
    143		xm = xm + ym;
    144
    145		if (xm >> (DP_FBITS + 1 + 3)) { /* carry out */
    146			xm = XDPSRS1(xm);	/* shift preserving sticky */
    147			xe++;
    148		}
    149	} else {
    150		if (xm >= ym) {
    151			xm = xm - ym;
    152		} else {
    153			xm = ym - xm;
    154			xs = ys;
    155		}
    156		if (xm == 0) {
    157			if (ieee754_csr.rm == FPU_CSR_RD)
    158				return ieee754dp_zero(1);	/* round negative inf. => sign = -1 */
    159			else
    160				return ieee754dp_zero(0);	/* other round modes   => sign = 1 */
    161		}
    162
    163		/* normalize to rounding precision
    164		 */
    165		while ((xm >> (DP_FBITS + 3)) == 0) {
    166			xm <<= 1;
    167			xe--;
    168		}
    169	}
    170
    171	return ieee754dp_format(xs, xe, xm);
    172}