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

sp_sub.c (4006B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/* IEEE754 floating point arithmetic
      3 * single precision
      4 */
      5/*
      6 * MIPS floating point support
      7 * Copyright (C) 1994-2000 Algorithmics Ltd.
      8 */
      9
     10#include "ieee754sp.h"
     11
     12union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
     13{
     14	int s;
     15
     16	COMPXSP;
     17	COMPYSP;
     18
     19	EXPLODEXSP;
     20	EXPLODEYSP;
     21
     22	ieee754_clearcx();
     23
     24	FLUSHXSP;
     25	FLUSHYSP;
     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 ieee754sp_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 ieee754sp_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 ieee754sp_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 ieee754sp_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 ieee754sp_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		SPSIGN(y) ^= 1;
     93		return y;
     94
     95	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
     96		SPDNORMX;
     97		fallthrough;
     98	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
     99		SPDNORMY;
    100		break;
    101
    102	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
    103		SPDNORMX;
    104		break;
    105
    106	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
    107		break;
    108	}
    109	/* flip sign of y and handle as add */
    110	ys ^= 1;
    111
    112	assert(xm & SP_HIDDEN_BIT);
    113	assert(ym & SP_HIDDEN_BIT);
    114
    115
    116	/* provide guard,round and stick bit space */
    117	xm <<= 3;
    118	ym <<= 3;
    119
    120	if (xe > ye) {
    121		/*
    122		 * have to shift y fraction right to align
    123		 */
    124		s = xe - ye;
    125		ym = XSPSRS(ym, s);
    126		ye += s;
    127	} else if (ye > xe) {
    128		/*
    129		 * have to shift x fraction right to align
    130		 */
    131		s = ye - xe;
    132		xm = XSPSRS(xm, s);
    133		xe += s;
    134	}
    135	assert(xe == ye);
    136	assert(xe <= SP_EMAX);
    137
    138	if (xs == ys) {
    139		/* generate 28 bit result of adding two 27 bit numbers
    140		 */
    141		xm = xm + ym;
    142
    143		if (xm >> (SP_FBITS + 1 + 3)) { /* carry out */
    144			SPXSRSX1();	/* shift preserving sticky */
    145		}
    146	} else {
    147		if (xm >= ym) {
    148			xm = xm - ym;
    149		} else {
    150			xm = ym - xm;
    151			xs = ys;
    152		}
    153		if (xm == 0) {
    154			if (ieee754_csr.rm == FPU_CSR_RD)
    155				return ieee754sp_zero(1);	/* round negative inf. => sign = -1 */
    156			else
    157				return ieee754sp_zero(0);	/* other round modes   => sign = 1 */
    158		}
    159		/* normalize to rounding precision
    160		 */
    161		while ((xm >> (SP_FBITS + 3)) == 0) {
    162			xm <<= 1;
    163			xe--;
    164		}
    165	}
    166
    167	return ieee754sp_format(xs, xe, xm);
    168}