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);
  70
  71int ieee754sp_tint(union ieee754sp x);
  72s64 ieee754sp_tlong(union ieee754sp x);
  73
  74int ieee754sp_cmp(union ieee754sp x, union ieee754sp y, int cop, int sig);
  75
  76union ieee754sp ieee754sp_sqrt(union ieee754sp x);
  77
  78/*
  79 * double precision (often aka double)
  80*/
  81int ieee754dp_class(union ieee754dp x);
  82
  83union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y);
  84union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y);
  85union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y);
  86union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y);
  87
  88union ieee754dp ieee754dp_abs(union ieee754dp x);
  89union ieee754dp ieee754dp_neg(union ieee754dp x);
  90
  91union ieee754dp ieee754dp_fint(int x);
  92union ieee754dp ieee754dp_flong(s64 x);
  93union ieee754dp ieee754dp_fsp(union ieee754sp x);
  94
  95int ieee754dp_tint(union ieee754dp x);
  96s64 ieee754dp_tlong(union ieee754dp x);
  97
  98int ieee754dp_cmp(union ieee754dp x, union ieee754dp y, int cop, int sig);
  99
 100union ieee754dp ieee754dp_sqrt(union ieee754dp x);
 101
 102
 103
 104/* 5 types of floating point number
 105*/
 106enum {
 107        IEEE754_CLASS_NORM      = 0x00,
 108        IEEE754_CLASS_ZERO      = 0x01,
 109        IEEE754_CLASS_DNORM     = 0x02,
 110        IEEE754_CLASS_INF       = 0x03,
 111        IEEE754_CLASS_SNAN      = 0x04,
 112        IEEE754_CLASS_QNAN      = 0x05,
 113};
 114
 115/* exception numbers */
 116#define IEEE754_INEXACT                 0x01
 117#define IEEE754_UNDERFLOW               0x02
 118#define IEEE754_OVERFLOW                0x04
 119#define IEEE754_ZERO_DIVIDE             0x08
 120#define IEEE754_INVALID_OPERATION       0x10
 121
 122/* cmp operators
 123*/
 124#define IEEE754_CLT     0x01
 125#define IEEE754_CEQ     0x02
 126#define IEEE754_CGT     0x04
 127#define IEEE754_CUN     0x08
 128
 129/* "normal" comparisons
 130*/
 131static inline int ieee754sp_eq(union ieee754sp x, union ieee754sp y)
 132{
 133        return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
 134}
 135
 136static inline int ieee754sp_ne(union ieee754sp x, union ieee754sp y)
 137{
 138        return ieee754sp_cmp(x, y,
 139                             IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
 140}
 141
 142static inline int ieee754sp_lt(union ieee754sp x, union ieee754sp y)
 143{
 144        return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
 145}
 146
 147static inline int ieee754sp_le(union ieee754sp x, union ieee754sp y)
 148{
 149        return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
 150}
 151
 152static inline int ieee754sp_gt(union ieee754sp x, union ieee754sp y)
 153{
 154        return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
 155}
 156
 157
 158static inline int ieee754sp_ge(union ieee754sp x, union ieee754sp y)
 159{
 160        return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
 161}
 162
 163static inline int ieee754dp_eq(union ieee754dp x, union ieee754dp y)
 164{
 165        return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
 166}
 167
 168static inline int ieee754dp_ne(union ieee754dp x, union ieee754dp y)
 169{
 170        return ieee754dp_cmp(x, y,
 171                             IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
 172}
 173
 174static inline int ieee754dp_lt(union ieee754dp x, union ieee754dp y)
 175{
 176        return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
 177}
 178
 179static inline int ieee754dp_le(union ieee754dp x, union ieee754dp y)
 180{
 181        return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
 182}
 183
 184static inline int ieee754dp_gt(union ieee754dp x, union ieee754dp y)
 185{
 186        return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
 187}
 188
 189static inline int ieee754dp_ge(union ieee754dp x, union ieee754dp y)
 190{
 191        return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
 192}
 193
 194/*
 195 * The control status register
 196 */
 197struct _ieee754_csr {
 198        __BITFIELD_FIELD(unsigned pad0:7,
 199        __BITFIELD_FIELD(unsigned nod:1,        /* set 1 for no denormalised numbers */
 200        __BITFIELD_FIELD(unsigned c:1,          /* condition */
 201        __BITFIELD_FIELD(unsigned pad1:5,
 202        __BITFIELD_FIELD(unsigned cx:6,         /* exceptions this operation */
 203        __BITFIELD_FIELD(unsigned mx:5,         /* exception enable  mask */
 204        __BITFIELD_FIELD(unsigned sx:5,         /* exceptions total */
 205        __BITFIELD_FIELD(unsigned rm:2,         /* current rounding mode */
 206        ;))))))))
 207};
 208#define ieee754_csr (*(struct _ieee754_csr *)(&current->thread.fpu.fcr31))
 209
 210static inline unsigned ieee754_getrm(void)
 211{
 212        return (ieee754_csr.rm);
 213}
 214static inline unsigned ieee754_setrm(unsigned rm)
 215{
 216        return (ieee754_csr.rm = rm);
 217}
 218
 219/*
 220 * get current exceptions
 221 */
 222static inline unsigned ieee754_getcx(void)
 223{
 224        return (ieee754_csr.cx);
 225}
 226
 227/* test for current exception condition
 228 */
 229static inline int ieee754_cxtest(unsigned n)
 230{
 231        return (ieee754_csr.cx & n);
 232}
 233
 234/*
 235 * get sticky exceptions
 236 */
 237static inline unsigned ieee754_getsx(void)
 238{
 239        return (ieee754_csr.sx);
 240}
 241
 242/* clear sticky conditions
 243*/
 244static inline unsigned ieee754_clrsx(void)
 245{
 246        return (ieee754_csr.sx = 0);
 247}
 248
 249/* test for sticky exception condition
 250 */
 251static inline int ieee754_sxtest(unsigned n)
 252{
 253        return (ieee754_csr.sx & n);
 254}
 255
 256/* debugging */
 257union ieee754sp ieee754sp_dump(char *s, union ieee754sp x);
 258union ieee754dp ieee754dp_dump(char *s, union ieee754dp x);
 259
 260#define IEEE754_SPCVAL_PZERO    0
 261#define IEEE754_SPCVAL_NZERO    1
 262#define IEEE754_SPCVAL_PONE     2
 263#define IEEE754_SPCVAL_NONE     3
 264#define IEEE754_SPCVAL_PTEN     4
 265#define IEEE754_SPCVAL_NTEN     5
 266#define IEEE754_SPCVAL_PINFINITY        6
 267#define IEEE754_SPCVAL_NINFINITY        7
 268#define IEEE754_SPCVAL_INDEF    8
 269#define IEEE754_SPCVAL_PMAX     9       /* +max norm */
 270#define IEEE754_SPCVAL_NMAX     10      /* -max norm */
 271#define IEEE754_SPCVAL_PMIN     11      /* +min norm */
 272#define IEEE754_SPCVAL_NMIN     12      /* +min norm */
 273#define IEEE754_SPCVAL_PMIND    13      /* +min denorm */
 274#define IEEE754_SPCVAL_NMIND    14      /* +min denorm */
 275#define IEEE754_SPCVAL_P1E31    15      /* + 1.0e31 */
 276#define IEEE754_SPCVAL_P1E63    16      /* + 1.0e63 */
 277
 278extern const union ieee754dp __ieee754dp_spcvals[];
 279extern const union ieee754sp __ieee754sp_spcvals[];
 280#define ieee754dp_spcvals ((const union ieee754dp *)__ieee754dp_spcvals)
 281#define ieee754sp_spcvals ((const union ieee754sp *)__ieee754sp_spcvals)
 282
 283/*
 284 * Return infinity with given sign
 285 */
 286#define ieee754dp_inf(sn)     (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
 287#define ieee754dp_zero(sn)      (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
 288#define ieee754dp_one(sn)       (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
 289#define ieee754dp_ten(sn)       (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
 290#define ieee754dp_indef()       (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
 291#define ieee754dp_max(sn)       (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
 292#define ieee754dp_min(sn)       (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
 293#define ieee754dp_mind(sn)      (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
 294#define ieee754dp_1e31()        (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
 295#define ieee754dp_1e63()        (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
 296
 297#define ieee754sp_inf(sn)     (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
 298#define ieee754sp_zero(sn)      (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
 299#define ieee754sp_one(sn)       (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
 300#define ieee754sp_ten(sn)       (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
 301#define ieee754sp_indef()       (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
 302#define ieee754sp_max(sn)       (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
 303#define ieee754sp_min(sn)       (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
 304#define ieee754sp_mind(sn)      (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
 305#define ieee754sp_1e31()        (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
 306#define ieee754sp_1e63()        (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
 307
 308/*
 309 * Indefinite integer value
 310 */
 311static inline int ieee754si_indef(void)
 312{
 313        return INT_MAX;
 314}
 315
 316static inline s64 ieee754di_indef(void)
 317{
 318        return S64_MAX;
 319}
 320
 321/* result types for xctx.rt */
 322#define IEEE754_RT_SP   0
 323#define IEEE754_RT_DP   1
 324#define IEEE754_RT_XP   2
 325#define IEEE754_RT_SI   3
 326#define IEEE754_RT_DI   4
 327
 328/* compat */
 329#define ieee754dp_fix(x)        ieee754dp_tint(x)
 330#define ieee754sp_fix(x)        ieee754sp_tint(x)
 331
 332#endif /* __ARCH_MIPS_MATH_EMU_IEEE754_H */
 333