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_fmax.c (6714B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * IEEE754 floating point arithmetic
      4 * single precision: MAX{,A}.f
      5 * MAX : Scalar Floating-Point Maximum
      6 * MAXA: Scalar Floating-Point argument with Maximum Absolute Value
      7 *
      8 * MAX.S : FPR[fd] = maxNum(FPR[fs],FPR[ft])
      9 * MAXA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
     10 *
     11 * MIPS floating point support
     12 * Copyright (C) 2015 Imagination Technologies, Ltd.
     13 * Author: Markos Chandras <markos.chandras@imgtec.com>
     14 */
     15
     16#include "ieee754sp.h"
     17
     18union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
     19{
     20	COMPXSP;
     21	COMPYSP;
     22
     23	EXPLODEXSP;
     24	EXPLODEYSP;
     25
     26	FLUSHXSP;
     27	FLUSHYSP;
     28
     29	ieee754_clearcx();
     30
     31	switch (CLPAIR(xc, yc)) {
     32	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
     33	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
     34	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
     35	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
     36	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
     37		return ieee754sp_nanxcpt(y);
     38
     39	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
     40	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
     41	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
     42	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
     43	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
     44	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
     45		return ieee754sp_nanxcpt(x);
     46
     47	/*
     48	 * Quiet NaN handling
     49	 */
     50
     51	/*
     52	 *    The case of both inputs quiet NaNs
     53	 */
     54	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
     55		return x;
     56
     57	/*
     58	 *    The cases of exactly one input quiet NaN (numbers
     59	 *    are here preferred as returned values to NaNs)
     60	 */
     61	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
     62	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
     63	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
     64	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
     65		return x;
     66
     67	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
     68	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
     69	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
     70	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
     71		return y;
     72
     73	/*
     74	 * Infinity and zero handling
     75	 */
     76	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
     77	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
     78	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
     79	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
     80	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
     81		return xs ? y : x;
     82
     83	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
     84	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
     85	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
     86	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
     87	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
     88	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
     89		return ys ? x : y;
     90
     91	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
     92		return ieee754sp_zero(xs & ys);
     93
     94	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
     95		SPDNORMX;
     96		fallthrough;
     97	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
     98		SPDNORMY;
     99		break;
    100
    101	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
    102		SPDNORMX;
    103	}
    104
    105	/* Finally get to do some computation */
    106
    107	assert(xm & SP_HIDDEN_BIT);
    108	assert(ym & SP_HIDDEN_BIT);
    109
    110	/* Compare signs */
    111	if (xs > ys)
    112		return y;
    113	else if (xs < ys)
    114		return x;
    115
    116	/* Signs of inputs are equal, let's compare exponents */
    117	if (xs == 0) {
    118		/* Inputs are both positive */
    119		if (xe > ye)
    120			return x;
    121		else if (xe < ye)
    122			return y;
    123	} else {
    124		/* Inputs are both negative */
    125		if (xe > ye)
    126			return y;
    127		else if (xe < ye)
    128			return x;
    129	}
    130
    131	/* Signs and exponents of inputs are equal, let's compare mantissas */
    132	if (xs == 0) {
    133		/* Inputs are both positive, with equal signs and exponents */
    134		if (xm <= ym)
    135			return y;
    136		return x;
    137	}
    138	/* Inputs are both negative, with equal signs and exponents */
    139	if (xm <= ym)
    140		return x;
    141	return y;
    142}
    143
    144union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
    145{
    146	COMPXSP;
    147	COMPYSP;
    148
    149	EXPLODEXSP;
    150	EXPLODEYSP;
    151
    152	FLUSHXSP;
    153	FLUSHYSP;
    154
    155	ieee754_clearcx();
    156
    157	switch (CLPAIR(xc, yc)) {
    158	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
    159	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
    160	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
    161	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
    162	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
    163		return ieee754sp_nanxcpt(y);
    164
    165	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
    166	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
    167	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
    168	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
    169	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
    170	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
    171		return ieee754sp_nanxcpt(x);
    172
    173	/*
    174	 * Quiet NaN handling
    175	 */
    176
    177	/*
    178	 *    The case of both inputs quiet NaNs
    179	 */
    180	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
    181		return x;
    182
    183	/*
    184	 *    The cases of exactly one input quiet NaN (numbers
    185	 *    are here preferred as returned values to NaNs)
    186	 */
    187	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
    188	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
    189	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
    190	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
    191		return x;
    192
    193	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
    194	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
    195	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
    196	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
    197		return y;
    198
    199	/*
    200	 * Infinity and zero handling
    201	 */
    202	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
    203		return ieee754sp_inf(xs & ys);
    204
    205	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
    206	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
    207	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
    208	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
    209	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
    210		return x;
    211
    212	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
    213	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
    214	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
    215	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
    216	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
    217		return y;
    218
    219	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
    220		return ieee754sp_zero(xs & ys);
    221
    222	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
    223		SPDNORMX;
    224		fallthrough;
    225	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
    226		SPDNORMY;
    227		break;
    228
    229	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
    230		SPDNORMX;
    231	}
    232
    233	/* Finally get to do some computation */
    234
    235	assert(xm & SP_HIDDEN_BIT);
    236	assert(ym & SP_HIDDEN_BIT);
    237
    238	/* Compare exponent */
    239	if (xe > ye)
    240		return x;
    241	else if (xe < ye)
    242		return y;
    243
    244	/* Compare mantissa */
    245	if (xm < ym)
    246		return y;
    247	else if (xm > ym)
    248		return x;
    249	else if (xs == 0)
    250		return x;
    251	return y;
    252}