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