Back to index

glibc  2.9
sfp-machine.h
Go to the documentation of this file.
00001 /* Machine-dependent software floating-point definitions.
00002    Sparc64 userland (_Q_* and _Qp_*) version.
00003    Copyright (C) 1997, 1998, 1999, 2006 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) and
00007                 David S. Miller (davem@redhat.com).
00008 
00009    The GNU C Library is free software; you can redistribute it and/or
00010    modify it under the terms of the GNU Lesser General Public
00011    License as published by the Free Software Foundation; either
00012    version 2.1 of the License, or (at your option) any later version.
00013 
00014    The GNU C Library is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017    Lesser General Public License for more details.
00018 
00019    You should have received a copy of the GNU Lesser General Public
00020    License along with the GNU C Library; if not, write to the Free
00021    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00022    02111-1307 USA.  */
00023    
00024 #include <fpu_control.h>
00025 #include <fenv.h>
00026 #include <stdlib.h>
00027 
00028 #define _FP_W_TYPE_SIZE            64
00029 #define _FP_W_TYPE          unsigned long
00030 #define _FP_WS_TYPE         signed long
00031 #define _FP_I_TYPE          long
00032 
00033 /* Helper macros for _FP_MUL_MEAT_2_120_240_double.  */
00034 #define _FP_MUL_MEAT_SET_FE_TZ                                 \
00035 do {                                                    \
00036   static fpu_control_t _fetz = _FPU_RC_DOWN;                   \
00037   _FPU_SETCW(_fetz);                                    \
00038 } while (0)
00039 #ifndef _FP_MUL_MEAT_RESET_FE
00040 #define _FP_MUL_MEAT_RESET_FE _FPU_SETCW(_fcw)
00041 #endif
00042       
00043 #define _FP_MUL_MEAT_S(R,X,Y)                                  \
00044   _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
00045 #define _FP_MUL_MEAT_D(R,X,Y)                                  \
00046   _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
00047 #define _FP_MUL_MEAT_Q(R,X,Y)                                  \
00048   _FP_MUL_MEAT_2_120_240_double(_FP_WFRACBITS_Q,R,X,Y,         \
00049                             _FP_MUL_MEAT_SET_FE_TZ,            \
00050                             _FP_MUL_MEAT_RESET_FE)
00051 
00052 #define _FP_DIV_MEAT_S(R,X,Y)      _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
00053 #define _FP_DIV_MEAT_D(R,X,Y)      _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
00054 #define _FP_DIV_MEAT_Q(R,X,Y)      _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
00055 
00056 #define _FP_NANFRAC_S              ((_FP_QNANBIT_S << 1) - 1)
00057 #define _FP_NANFRAC_D              ((_FP_QNANBIT_D << 1) - 1)
00058 #define _FP_NANFRAC_Q              ((_FP_QNANBIT_Q << 1) - 1), -1
00059 #define _FP_NANSIGN_S              0
00060 #define _FP_NANSIGN_D              0
00061 #define _FP_NANSIGN_Q              0
00062 
00063 #define _FP_KEEPNANFRACP 1
00064 
00065 /* If one NaN is signaling and the other is not,
00066  * we choose that one, otherwise we choose Y.
00067  */
00068 #define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
00069   do {                                                  \
00070     if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)         \
00071        && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))     \
00072       {                                                        \
00073        R##_s = X##_s;                                          \
00074        _FP_FRAC_COPY_##wc(R,X);                         \
00075       }                                                        \
00076     else                                                \
00077       {                                                        \
00078        R##_s = Y##_s;                                          \
00079        _FP_FRAC_COPY_##wc(R,Y);                         \
00080       }                                                        \
00081     R##_c = FP_CLS_NAN;                                        \
00082   } while (0)
00083 
00084 /* Obtain the current rounding mode. */
00085 #ifndef FP_ROUNDMODE
00086 #define FP_ROUNDMODE ((_fcw >> 30) & 0x3)
00087 #endif
00088 
00089 /* Exception flags. */
00090 #define FP_EX_INVALID              (1 << 4)
00091 #define FP_EX_OVERFLOW             (1 << 3)
00092 #define FP_EX_UNDERFLOW            (1 << 2)
00093 #define FP_EX_DIVZERO              (1 << 1)
00094 #define FP_EX_INEXACT              (1 << 0)
00095 
00096 #define _FP_DECL_EX  fpu_control_t _fcw
00097 
00098 #define FP_INIT_ROUNDMODE                               \
00099 do {                                                    \
00100   _FPU_GETCW(_fcw);                                     \
00101 } while (0)
00102 
00103 #define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex)
00104 
00105 /* Simulate exceptions using double arithmetics. */
00106 extern double __Qp_handle_exceptions(int exc);
00107 
00108 #define FP_HANDLE_EXCEPTIONS                                   \
00109 do {                                                    \
00110   if (!_fex)                                            \
00111     {                                                   \
00112       /* This is the common case, so we do it inline.          \
00113        * We need to clear cexc bits if any.                    \
00114        */                                               \
00115       __asm__ __volatile__("\n"                                \
00116 "             fzero %%f62\n"                                          \
00117 "             faddd %%f62, %%f62, %%f62\n"                            \
00118 "             " : : : "f62");                                         \
00119     }                                                   \
00120   else                                                  \
00121     {                                                   \
00122       __Qp_handle_exceptions (_fex);                           \
00123     }                                                   \
00124 } while (0)
00125 
00126 #define QP_HANDLE_EXCEPTIONS(_a)                        \
00127 do {                                                    \
00128   if ((_fcw >> 23) & _fex)                              \
00129     {                                                   \
00130       _a;                                               \
00131     }                                                   \
00132   else                                                  \
00133     {                                                   \
00134       _fcw = (_fcw & ~0x1fL) | (_fex << 5) | _fex;             \
00135       _FPU_SETCW(_fcw);                                        \
00136     }                                                   \
00137 } while (0)
00138 
00139 #define QP_NO_EXCEPTIONS                                \
00140   __asm ("fzero %%f62\n"                                \
00141 "        faddd %%f62, %%f62, %%f62" : : : "f62")
00142                               
00143 #define QP_CLOBBER "memory", "f52", "f54", "f56", "f58", "f60", "f62"
00144 #define QP_CLOBBER_CC QP_CLOBBER , "cc"