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


      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_add(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_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 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		return y;
     92
     93	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
     94		SPDNORMX;
     95		fallthrough;
     96	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
     97		SPDNORMY;
     98		break;
     99
    100	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
    101		SPDNORMX;
    102		break;
    103
    104	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
    105		break;
    106	}
    107	assert(xm & SP_HIDDEN_BIT);
    108	assert(ym & SP_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 = XSPSRS(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 = XSPSRS(xm, s);
    129		xe += s;
    130	}
    131	assert(xe == ye);
    132	assert(xe <= SP_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 >> (SP_FBITS + 1 + 3)) { /* carry out */
    142			SPXSRSX1();
    143		}
    144	} else {
    145		if (xm >= ym) {
    146			xm = xm - ym;
    147		} else {
    148			xm = ym - xm;
    149			xs = ys;
    150		}
    151		if (xm == 0)
    152			return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
    153
    154		/*
    155		 * Normalize in extended single precision
    156		 */
    157		while ((xm >> (SP_FBITS + 3)) == 0) {
    158			xm <<= 1;
    159			xe--;
    160		}
    161	}
    162
    163	return ieee754sp_format(xs, xe, xm);
    164}