linux/arch/mips/math-emu/ieee754.h
<<
>>
Prefs
   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 */
 312