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_mul.c (3941B)


      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_mul(union ieee754sp x, union ieee754sp y)
     13{
     14	int re;
     15	int rs;
     16	unsigned int rm;
     17	unsigned short lxm;
     18	unsigned short hxm;
     19	unsigned short lym;
     20	unsigned short hym;
     21	unsigned int lrm;
     22	unsigned int hrm;
     23	unsigned int t;
     24	unsigned int at;
     25
     26	COMPXSP;
     27	COMPYSP;
     28
     29	EXPLODEXSP;
     30	EXPLODEYSP;
     31
     32	ieee754_clearcx();
     33
     34	FLUSHXSP;
     35	FLUSHYSP;
     36
     37	switch (CLPAIR(xc, yc)) {
     38	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
     39	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
     40	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
     41	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
     42	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
     43		return ieee754sp_nanxcpt(y);
     44
     45	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
     46	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
     47	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
     48	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
     49	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
     50	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
     51		return ieee754sp_nanxcpt(x);
     52
     53	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
     54	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
     55	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
     56	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
     57		return y;
     58
     59	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
     60	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
     61	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
     62	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
     63	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
     64		return x;
     65
     66
     67	/*
     68	 * Infinity handling
     69	 */
     70	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
     71	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
     72		ieee754_setcx(IEEE754_INVALID_OPERATION);
     73		return ieee754sp_indef();
     74
     75	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
     76	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
     77	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
     78	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
     79	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
     80		return ieee754sp_inf(xs ^ ys);
     81
     82	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
     83	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
     84	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
     85	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
     86	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
     87		return ieee754sp_zero(xs ^ ys);
     88
     89
     90	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
     91		SPDNORMX;
     92		fallthrough;
     93	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
     94		SPDNORMY;
     95		break;
     96
     97	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
     98		SPDNORMX;
     99		break;
    100
    101	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
    102		break;
    103	}
    104	/* rm = xm * ym, re = xe+ye basically */
    105	assert(xm & SP_HIDDEN_BIT);
    106	assert(ym & SP_HIDDEN_BIT);
    107
    108	re = xe + ye;
    109	rs = xs ^ ys;
    110
    111	/* shunt to top of word */
    112	xm <<= 32 - (SP_FBITS + 1);
    113	ym <<= 32 - (SP_FBITS + 1);
    114
    115	/*
    116	 * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
    117	 */
    118	lxm = xm & 0xffff;
    119	hxm = xm >> 16;
    120	lym = ym & 0xffff;
    121	hym = ym >> 16;
    122
    123	lrm = lxm * lym;	/* 16 * 16 => 32 */
    124	hrm = hxm * hym;	/* 16 * 16 => 32 */
    125
    126	t = lxm * hym; /* 16 * 16 => 32 */
    127	at = lrm + (t << 16);
    128	hrm += at < lrm;
    129	lrm = at;
    130	hrm = hrm + (t >> 16);
    131
    132	t = hxm * lym; /* 16 * 16 => 32 */
    133	at = lrm + (t << 16);
    134	hrm += at < lrm;
    135	lrm = at;
    136	hrm = hrm + (t >> 16);
    137
    138	rm = hrm | (lrm != 0);
    139
    140	/*
    141	 * Sticky shift down to normal rounding precision.
    142	 */
    143	if ((int) rm < 0) {
    144		rm = (rm >> (32 - (SP_FBITS + 1 + 3))) |
    145		    ((rm << (SP_FBITS + 1 + 3)) != 0);
    146		re++;
    147	} else {
    148		rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) |
    149		     ((rm << (SP_FBITS + 1 + 3 + 1)) != 0);
    150	}
    151	assert(rm & (SP_HIDDEN_BIT << 3));
    152
    153	return ieee754sp_format(rs, re, rm);
    154}