Back to index

glibc  2.9
soft-fp.h
Go to the documentation of this file.
00001 /* Software floating-point emulation.
00002    Copyright (C) 1997,1998,1999,2000,2002,2003,2005,2006,2007
00003        Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005    Contributed by Richard Henderson (rth@cygnus.com),
00006                 Jakub Jelinek (jj@ultra.linux.cz),
00007                 David S. Miller (davem@redhat.com) and
00008                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
00009 
00010    The GNU C Library is free software; you can redistribute it and/or
00011    modify it under the terms of the GNU Lesser General Public
00012    License as published by the Free Software Foundation; either
00013    version 2.1 of the License, or (at your option) any later version.
00014 
00015    In addition to the permissions in the GNU Lesser General Public
00016    License, the Free Software Foundation gives you unlimited
00017    permission to link the compiled version of this file into
00018    combinations with other programs, and to distribute those
00019    combinations without any restriction coming from the use of this
00020    file.  (The Lesser General Public License restrictions do apply in
00021    other respects; for example, they cover modification of the file,
00022    and distribution when not linked into a combine executable.)
00023 
00024    The GNU C Library is distributed in the hope that it will be useful,
00025    but WITHOUT ANY WARRANTY; without even the implied warranty of
00026    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00027    Lesser General Public License for more details.
00028 
00029    You should have received a copy of the GNU Lesser General Public
00030    License along with the GNU C Library; if not, write to the Free
00031    Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
00032    MA 02110-1301, USA.  */
00033 
00034 #ifndef SOFT_FP_H
00035 #define SOFT_FP_H
00036 
00037 #ifdef _LIBC
00038 #include <sfp-machine.h>
00039 #else
00040 #include "sfp-machine.h"
00041 #endif
00042 
00043 /* Allow sfp-machine to have its own byte order definitions. */
00044 #ifndef __BYTE_ORDER
00045 #ifdef _LIBC
00046 #include <endian.h>
00047 #else
00048 #error "endianness not defined by sfp-machine.h"
00049 #endif
00050 #endif
00051 
00052 #define _FP_WORKBITS        3
00053 #define _FP_WORK_LSB        ((_FP_W_TYPE)1 << 3)
00054 #define _FP_WORK_ROUND             ((_FP_W_TYPE)1 << 2)
00055 #define _FP_WORK_GUARD             ((_FP_W_TYPE)1 << 1)
00056 #define _FP_WORK_STICKY            ((_FP_W_TYPE)1 << 0)
00057 
00058 #ifndef FP_RND_NEAREST
00059 # define FP_RND_NEAREST            0
00060 # define FP_RND_ZERO        1
00061 # define FP_RND_PINF        2
00062 # define FP_RND_MINF        3
00063 #endif
00064 #ifndef FP_ROUNDMODE
00065 # define FP_ROUNDMODE              FP_RND_NEAREST
00066 #endif
00067 
00068 /* By default don't care about exceptions. */
00069 #ifndef FP_EX_INVALID
00070 #define FP_EX_INVALID              0
00071 #endif
00072 #ifndef FP_EX_OVERFLOW
00073 #define FP_EX_OVERFLOW             0
00074 #endif
00075 #ifndef FP_EX_UNDERFLOW
00076 #define FP_EX_UNDERFLOW            0
00077 #endif
00078 #ifndef FP_EX_DIVZERO
00079 #define FP_EX_DIVZERO              0
00080 #endif
00081 #ifndef FP_EX_INEXACT
00082 #define FP_EX_INEXACT              0
00083 #endif
00084 #ifndef FP_EX_DENORM
00085 #define FP_EX_DENORM        0
00086 #endif
00087 
00088 #ifdef _FP_DECL_EX
00089 #define FP_DECL_EX                               \
00090   int _fex = 0;                                         \
00091   _FP_DECL_EX
00092 #else
00093 #define FP_DECL_EX int _fex = 0
00094 #endif
00095 
00096 #ifndef FP_INIT_ROUNDMODE
00097 #define FP_INIT_ROUNDMODE do {} while (0)
00098 #endif
00099 
00100 #ifndef FP_HANDLE_EXCEPTIONS
00101 #define FP_HANDLE_EXCEPTIONS do {} while (0)
00102 #endif
00103 
00104 #ifndef FP_INHIBIT_RESULTS
00105 /* By default we write the results always.
00106  * sfp-machine may override this and e.g.
00107  * check if some exceptions are unmasked
00108  * and inhibit it in such a case.
00109  */
00110 #define FP_INHIBIT_RESULTS 0
00111 #endif
00112 
00113 #define FP_SET_EXCEPTION(ex)                            \
00114   _fex |= (ex)
00115 
00116 #define FP_UNSET_EXCEPTION(ex)                          \
00117   _fex &= ~(ex)
00118 
00119 #define FP_CLEAR_EXCEPTIONS                      \
00120   _fex = 0
00121 
00122 #define _FP_ROUND_NEAREST(wc, X)                 \
00123 do {                                             \
00124     if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND)  \
00125       _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);            \
00126 } while (0)
00127 
00128 #define _FP_ROUND_ZERO(wc, X)             (void)0
00129 
00130 #define _FP_ROUND_PINF(wc, X)                           \
00131 do {                                             \
00132     if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7))           \
00133       _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);              \
00134 } while (0)
00135 
00136 #define _FP_ROUND_MINF(wc, X)                           \
00137 do {                                             \
00138     if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7))            \
00139       _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);              \
00140 } while (0)
00141 
00142 #define _FP_ROUND(wc, X)                  \
00143 do {                                      \
00144        if (_FP_FRAC_LOW_##wc(X) & 7)             \
00145          FP_SET_EXCEPTION(FP_EX_INEXACT); \
00146        switch (FP_ROUNDMODE)                     \
00147        {                                  \
00148          case FP_RND_NEAREST:                    \
00149            _FP_ROUND_NEAREST(wc,X);              \
00150            break;                         \
00151          case FP_RND_ZERO:                \
00152            _FP_ROUND_ZERO(wc,X);          \
00153            break;                         \
00154          case FP_RND_PINF:                \
00155            _FP_ROUND_PINF(wc,X);          \
00156            break;                         \
00157          case FP_RND_MINF:                \
00158            _FP_ROUND_MINF(wc,X);          \
00159            break;                         \
00160        }                                  \
00161 } while (0)
00162 
00163 #define FP_CLS_NORMAL              0
00164 #define FP_CLS_ZERO         1
00165 #define FP_CLS_INF          2
00166 #define FP_CLS_NAN          3
00167 
00168 #define _FP_CLS_COMBINE(x,y)       (((x) << 2) | (y))
00169 
00170 #include "op-1.h"
00171 #include "op-2.h"
00172 #include "op-4.h"
00173 #include "op-8.h"
00174 #include "op-common.h"
00175 
00176 /* Sigh.  Silly things longlong.h needs.  */
00177 #define UWtype              _FP_W_TYPE
00178 #define W_TYPE_SIZE  _FP_W_TYPE_SIZE
00179 
00180 typedef int QItype __attribute__((mode(QI)));
00181 typedef int SItype __attribute__((mode(SI)));
00182 typedef int DItype __attribute__((mode(DI)));
00183 typedef unsigned int UQItype __attribute__((mode(QI)));
00184 typedef unsigned int USItype __attribute__((mode(SI)));
00185 typedef unsigned int UDItype __attribute__((mode(DI)));
00186 #if _FP_W_TYPE_SIZE == 32
00187 typedef unsigned int UHWtype __attribute__((mode(HI)));
00188 #elif _FP_W_TYPE_SIZE == 64
00189 typedef USItype UHWtype;
00190 #endif
00191 
00192 #ifndef CMPtype
00193 #define CMPtype             int
00194 #endif
00195 
00196 #define SI_BITS             (__CHAR_BIT__ * (int)sizeof(SItype))
00197 #define DI_BITS             (__CHAR_BIT__ * (int)sizeof(DItype))
00198 
00199 #ifndef umul_ppmm
00200 #ifdef _LIBC
00201 #include <stdlib/longlong.h>
00202 #else
00203 #include "longlong.h"
00204 #endif
00205 #endif
00206 
00207 #ifdef _LIBC
00208 #include <stdlib.h>
00209 #else
00210 extern void abort (void);
00211 #endif
00212 
00213 #endif