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


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * IEEE754 floating point arithmetic
      4 * double precision: MIN{,A}.f
      5 * MIN : Scalar Floating-Point Minimum
      6 * MINA: Scalar Floating-Point argument with Minimum Absolute Value
      7 *
      8 * MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft])
      9 * MINA.D: 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 "ieee754dp.h"
     17
     18union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
     19{
     20	COMPXDP;
     21	COMPYDP;
     22
     23	EXPLODEXDP;
     24	EXPLODEYDP;
     25
     26	FLUSHXDP;
     27	FLUSHYDP;
     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 ieee754dp_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 ieee754dp_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 ieee754dp_zero(xs & ys);
     93
     94	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
     95		DPDNORMX;
     96		fallthrough;
     97	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
     98		DPDNORMY;
     99		break;
    100
    101	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
    102		DPDNORMX;
    103	}
    104
    105	/* Finally get to do some computation */
    106
    107	assert(xm & DP_HIDDEN_BIT);
    108	assert(ym & DP_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 ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
    145{
    146	COMPXDP;
    147	COMPYDP;
    148
    149	EXPLODEXDP;
    150	EXPLODEYDP;
    151
    152	FLUSHXDP;
    153	FLUSHYDP;
    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 ieee754dp_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 ieee754dp_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 ieee754dp_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 ieee754dp_zero(xs & ys);
    221
    222	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
    223		DPDNORMX;
    224		fallthrough;
    225	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
    226		DPDNORMY;
    227		break;
    228
    229	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
    230		DPDNORMX;
    231	}
    232
    233	/* Finally get to do some computation */
    234
    235	assert(xm & DP_HIDDEN_BIT);
    236	assert(ym & DP_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}