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

ieee754.h (9992B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * MIPS floating point support
      4 * Copyright (C) 1994-2000 Algorithmics Ltd.
      5 *
      6 *  Nov 7, 2000
      7 *  Modification to allow integration with Linux kernel
      8 *
      9 *  Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
     10 *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
     11 */
     12#ifndef __ARCH_MIPS_MATH_EMU_IEEE754_H
     13#define __ARCH_MIPS_MATH_EMU_IEEE754_H
     14
     15#include <linux/compiler.h>
     16#include <asm/byteorder.h>
     17#include <linux/kernel.h>
     18#include <linux/types.h>
     19#include <linux/sched.h>
     20#include <asm/bitfield.h>
     21
     22union ieee754dp {
     23	struct {
     24		__BITFIELD_FIELD(unsigned int sign:1,
     25		__BITFIELD_FIELD(unsigned int bexp:11,
     26		__BITFIELD_FIELD(u64 mant:52,
     27		;)))
     28	};
     29	u64 bits;
     30};
     31
     32union ieee754sp {
     33	struct {
     34		__BITFIELD_FIELD(unsigned sign:1,
     35		__BITFIELD_FIELD(unsigned bexp:8,
     36		__BITFIELD_FIELD(unsigned mant:23,
     37		;)))
     38	};
     39	u32 bits;
     40};
     41
     42/*
     43 * single precision (often aka float)
     44*/
     45int ieee754sp_class(union ieee754sp x);
     46
     47union ieee754sp ieee754sp_abs(union ieee754sp x);
     48union ieee754sp ieee754sp_neg(union ieee754sp x);
     49
     50union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y);
     51union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y);
     52union ieee754sp ieee754sp_mul(union ieee754sp x, union ieee754sp y);
     53union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y);
     54
     55union ieee754sp ieee754sp_fint(int x);
     56union ieee754sp ieee754sp_flong(s64 x);
     57union ieee754sp ieee754sp_fdp(union ieee754dp x);
     58union ieee754sp ieee754sp_rint(union ieee754sp x);
     59
     60int ieee754sp_tint(union ieee754sp x);
     61s64 ieee754sp_tlong(union ieee754sp x);
     62
     63int ieee754sp_cmp(union ieee754sp x, union ieee754sp y, int cop, int sig);
     64
     65union ieee754sp ieee754sp_sqrt(union ieee754sp x);
     66
     67union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x,
     68				union ieee754sp y);
     69union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
     70				union ieee754sp y);
     71union ieee754sp ieee754sp_madd(union ieee754sp z, union ieee754sp x,
     72				union ieee754sp y);
     73union ieee754sp ieee754sp_msub(union ieee754sp z, union ieee754sp x,
     74				union ieee754sp y);
     75union ieee754sp ieee754sp_nmadd(union ieee754sp z, union ieee754sp x,
     76				union ieee754sp y);
     77union ieee754sp ieee754sp_nmsub(union ieee754sp z, union ieee754sp x,
     78				union ieee754sp y);
     79int ieee754sp_2008class(union ieee754sp x);
     80union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y);
     81union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y);
     82union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y);
     83union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y);
     84
     85/*
     86 * double precision (often aka double)
     87*/
     88int ieee754dp_class(union ieee754dp x);
     89
     90union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y);
     91union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y);
     92union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y);
     93union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y);
     94
     95union ieee754dp ieee754dp_abs(union ieee754dp x);
     96union ieee754dp ieee754dp_neg(union ieee754dp x);
     97
     98union ieee754dp ieee754dp_fint(int x);
     99union ieee754dp ieee754dp_flong(s64 x);
    100union ieee754dp ieee754dp_fsp(union ieee754sp x);
    101union ieee754dp ieee754dp_rint(union ieee754dp x);
    102
    103int ieee754dp_tint(union ieee754dp x);
    104s64 ieee754dp_tlong(union ieee754dp x);
    105
    106int ieee754dp_cmp(union ieee754dp x, union ieee754dp y, int cop, int sig);
    107
    108union ieee754dp ieee754dp_sqrt(union ieee754dp x);
    109
    110union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
    111				union ieee754dp y);
    112union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
    113				union ieee754dp y);
    114union ieee754dp ieee754dp_madd(union ieee754dp z, union ieee754dp x,
    115				union ieee754dp y);
    116union ieee754dp ieee754dp_msub(union ieee754dp z, union ieee754dp x,
    117				union ieee754dp y);
    118union ieee754dp ieee754dp_nmadd(union ieee754dp z, union ieee754dp x,
    119				union ieee754dp y);
    120union ieee754dp ieee754dp_nmsub(union ieee754dp z, union ieee754dp x,
    121				union ieee754dp y);
    122int ieee754dp_2008class(union ieee754dp x);
    123union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y);
    124union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y);
    125union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y);
    126union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y);
    127
    128
    129/* 5 types of floating point number
    130*/
    131enum {
    132	IEEE754_CLASS_NORM	= 0x00,
    133	IEEE754_CLASS_ZERO	= 0x01,
    134	IEEE754_CLASS_DNORM	= 0x02,
    135	IEEE754_CLASS_INF	= 0x03,
    136	IEEE754_CLASS_SNAN	= 0x04,
    137	IEEE754_CLASS_QNAN	= 0x05,
    138};
    139
    140/* exception numbers */
    141#define IEEE754_INEXACT			0x01
    142#define IEEE754_UNDERFLOW		0x02
    143#define IEEE754_OVERFLOW		0x04
    144#define IEEE754_ZERO_DIVIDE		0x08
    145#define IEEE754_INVALID_OPERATION	0x10
    146
    147/* cmp operators
    148*/
    149#define IEEE754_CLT	0x01
    150#define IEEE754_CEQ	0x02
    151#define IEEE754_CGT	0x04
    152#define IEEE754_CUN	0x08
    153
    154/*
    155 * The control status register
    156 */
    157struct _ieee754_csr {
    158	__BITFIELD_FIELD(unsigned fcc:7,	/* condition[7:1] */
    159	__BITFIELD_FIELD(unsigned nod:1,	/* set 1 for no denormals */
    160	__BITFIELD_FIELD(unsigned c:1,		/* condition[0] */
    161	__BITFIELD_FIELD(unsigned pad0:3,
    162	__BITFIELD_FIELD(unsigned abs2008:1,	/* IEEE 754-2008 ABS/NEG.fmt */
    163	__BITFIELD_FIELD(unsigned nan2008:1,	/* IEEE 754-2008 NaN mode */
    164	__BITFIELD_FIELD(unsigned cx:6,		/* exceptions this operation */
    165	__BITFIELD_FIELD(unsigned mx:5,		/* exception enable  mask */
    166	__BITFIELD_FIELD(unsigned sx:5,		/* exceptions total */
    167	__BITFIELD_FIELD(unsigned rm:2,		/* current rounding mode */
    168	;))))))))))
    169};
    170#define ieee754_csr (*(struct _ieee754_csr *)(&current->thread.fpu.fcr31))
    171
    172static inline unsigned int ieee754_getrm(void)
    173{
    174	return (ieee754_csr.rm);
    175}
    176
    177static inline unsigned int ieee754_setrm(unsigned int rm)
    178{
    179	return (ieee754_csr.rm = rm);
    180}
    181
    182/*
    183 * get current exceptions
    184 */
    185static inline unsigned int ieee754_getcx(void)
    186{
    187	return (ieee754_csr.cx);
    188}
    189
    190/* test for current exception condition
    191 */
    192static inline int ieee754_cxtest(unsigned int n)
    193{
    194	return (ieee754_csr.cx & n);
    195}
    196
    197/*
    198 * get sticky exceptions
    199 */
    200static inline unsigned int ieee754_getsx(void)
    201{
    202	return (ieee754_csr.sx);
    203}
    204
    205/* clear sticky conditions
    206*/
    207static inline unsigned int ieee754_clrsx(void)
    208{
    209	return (ieee754_csr.sx = 0);
    210}
    211
    212/* test for sticky exception condition
    213 */
    214static inline int ieee754_sxtest(unsigned int n)
    215{
    216	return (ieee754_csr.sx & n);
    217}
    218
    219/* debugging */
    220union ieee754sp ieee754sp_dump(char *s, union ieee754sp x);
    221union ieee754dp ieee754dp_dump(char *s, union ieee754dp x);
    222
    223#define IEEE754_SPCVAL_PZERO		0	/* +0.0 */
    224#define IEEE754_SPCVAL_NZERO		1	/* -0.0 */
    225#define IEEE754_SPCVAL_PONE		2	/* +1.0 */
    226#define IEEE754_SPCVAL_NONE		3	/* -1.0 */
    227#define IEEE754_SPCVAL_PTEN		4	/* +10.0 */
    228#define IEEE754_SPCVAL_NTEN		5	/* -10.0 */
    229#define IEEE754_SPCVAL_PINFINITY	6	/* +inf */
    230#define IEEE754_SPCVAL_NINFINITY	7	/* -inf */
    231#define IEEE754_SPCVAL_INDEF_LEG	8	/* legacy quiet NaN */
    232#define IEEE754_SPCVAL_INDEF_2008	9	/* IEEE 754-2008 quiet NaN */
    233#define IEEE754_SPCVAL_PMAX		10	/* +max norm */
    234#define IEEE754_SPCVAL_NMAX		11	/* -max norm */
    235#define IEEE754_SPCVAL_PMIN		12	/* +min norm */
    236#define IEEE754_SPCVAL_NMIN		13	/* -min norm */
    237#define IEEE754_SPCVAL_PMIND		14	/* +min denorm */
    238#define IEEE754_SPCVAL_NMIND		15	/* -min denorm */
    239#define IEEE754_SPCVAL_P1E31		16	/* + 1.0e31 */
    240#define IEEE754_SPCVAL_P1E63		17	/* + 1.0e63 */
    241
    242extern const union ieee754dp __ieee754dp_spcvals[];
    243extern const union ieee754sp __ieee754sp_spcvals[];
    244#define ieee754dp_spcvals ((const union ieee754dp *)__ieee754dp_spcvals)
    245#define ieee754sp_spcvals ((const union ieee754sp *)__ieee754sp_spcvals)
    246
    247/*
    248 * Return infinity with given sign
    249 */
    250#define ieee754dp_inf(sn)     (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
    251#define ieee754dp_zero(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
    252#define ieee754dp_one(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
    253#define ieee754dp_ten(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
    254#define ieee754dp_indef()	(ieee754dp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \
    255						   ieee754_csr.nan2008])
    256#define ieee754dp_max(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
    257#define ieee754dp_min(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
    258#define ieee754dp_mind(sn)	(ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
    259#define ieee754dp_1e31()	(ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
    260#define ieee754dp_1e63()	(ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
    261
    262#define ieee754sp_inf(sn)     (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
    263#define ieee754sp_zero(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
    264#define ieee754sp_one(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
    265#define ieee754sp_ten(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
    266#define ieee754sp_indef()	(ieee754sp_spcvals[IEEE754_SPCVAL_INDEF_LEG + \
    267						   ieee754_csr.nan2008])
    268#define ieee754sp_max(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
    269#define ieee754sp_min(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
    270#define ieee754sp_mind(sn)	(ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
    271#define ieee754sp_1e31()	(ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
    272#define ieee754sp_1e63()	(ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
    273
    274/*
    275 * Indefinite integer value
    276 */
    277static inline int ieee754si_indef(void)
    278{
    279	return ieee754_csr.nan2008 ? 0 : INT_MAX;
    280}
    281
    282static inline s64 ieee754di_indef(void)
    283{
    284	return ieee754_csr.nan2008 ? 0 : S64_MAX;
    285}
    286
    287/*
    288 * Overflow integer value
    289 */
    290static inline int ieee754si_overflow(int xs)
    291{
    292	return ieee754_csr.nan2008 && xs ? INT_MIN : INT_MAX;
    293}
    294
    295static inline s64 ieee754di_overflow(int xs)
    296{
    297	return ieee754_csr.nan2008 && xs ? S64_MIN : S64_MAX;
    298}
    299
    300/* result types for xctx.rt */
    301#define IEEE754_RT_SP	0
    302#define IEEE754_RT_DP	1
    303#define IEEE754_RT_XP	2
    304#define IEEE754_RT_SI	3
    305#define IEEE754_RT_DI	4
    306
    307/* compat */
    308#define ieee754dp_fix(x)	ieee754dp_tint(x)
    309#define ieee754sp_fix(x)	ieee754sp_tint(x)
    310
    311#endif /* __ARCH_MIPS_MATH_EMU_IEEE754_H */