Home | History | Annotate | Line # | Download | only in soft-fp
soft-fp.h revision 1.1.1.2
      1 /* Software floating-point emulation.
      2    Copyright (C) 1997-2014 Free Software Foundation, Inc.
      3    This file is part of the GNU C Library.
      4    Contributed by Richard Henderson (rth (at) cygnus.com),
      5 		  Jakub Jelinek (jj (at) ultra.linux.cz),
      6 		  David S. Miller (davem (at) redhat.com) and
      7 		  Peter Maydell (pmaydell (at) chiark.greenend.org.uk).
      8 
      9    The GNU C Library is free software; you can redistribute it and/or
     10    modify it under the terms of the GNU Lesser General Public
     11    License as published by the Free Software Foundation; either
     12    version 2.1 of the License, or (at your option) any later version.
     13 
     14    In addition to the permissions in the GNU Lesser General Public
     15    License, the Free Software Foundation gives you unlimited
     16    permission to link the compiled version of this file into
     17    combinations with other programs, and to distribute those
     18    combinations without any restriction coming from the use of this
     19    file.  (The Lesser General Public License restrictions do apply in
     20    other respects; for example, they cover modification of the file,
     21    and distribution when not linked into a combine executable.)
     22 
     23    The GNU C Library is distributed in the hope that it will be useful,
     24    but WITHOUT ANY WARRANTY; without even the implied warranty of
     25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     26    Lesser General Public License for more details.
     27 
     28    You should have received a copy of the GNU Lesser General Public
     29    License along with the GNU C Library; if not, see
     30    <http://www.gnu.org/licenses/>.  */
     31 
     32 #ifndef SOFT_FP_H
     33 #define SOFT_FP_H
     34 
     35 #ifdef _LIBC
     36 # include <sfp-machine.h>
     37 #else
     38 # include "sfp-machine.h"
     39 #endif
     40 
     41 /* Allow sfp-machine to have its own byte order definitions.  */
     42 #ifndef __BYTE_ORDER
     43 # ifdef _LIBC
     44 #  include <endian.h>
     45 # else
     46 #  error "endianness not defined by sfp-machine.h"
     47 # endif
     48 #endif
     49 
     50 #define _FP_WORKBITS		3
     51 #define _FP_WORK_LSB		((_FP_W_TYPE) 1 << 3)
     52 #define _FP_WORK_ROUND		((_FP_W_TYPE) 1 << 2)
     53 #define _FP_WORK_GUARD		((_FP_W_TYPE) 1 << 1)
     54 #define _FP_WORK_STICKY		((_FP_W_TYPE) 1 << 0)
     55 
     56 #ifndef FP_RND_NEAREST
     57 # define FP_RND_NEAREST		0
     58 # define FP_RND_ZERO		1
     59 # define FP_RND_PINF		2
     60 # define FP_RND_MINF		3
     61 #endif
     62 #ifndef FP_ROUNDMODE
     63 # define FP_ROUNDMODE		FP_RND_NEAREST
     64 #endif
     65 
     66 /* By default don't care about exceptions.  */
     67 #ifndef FP_EX_INVALID
     68 # define FP_EX_INVALID		0
     69 #endif
     70 #ifndef FP_EX_OVERFLOW
     71 # define FP_EX_OVERFLOW		0
     72 #endif
     73 #ifndef FP_EX_UNDERFLOW
     74 # define FP_EX_UNDERFLOW	0
     75 #endif
     76 #ifndef FP_EX_DIVZERO
     77 # define FP_EX_DIVZERO		0
     78 #endif
     79 #ifndef FP_EX_INEXACT
     80 # define FP_EX_INEXACT		0
     81 #endif
     82 #ifndef FP_EX_DENORM
     83 # define FP_EX_DENORM		0
     84 #endif
     85 
     86 /* Sub-exceptions of "invalid".  */
     87 /* Signaling NaN operand.  */
     88 #ifndef FP_EX_INVALID_SNAN
     89 # define FP_EX_INVALID_SNAN	0
     90 #endif
     91 /* Inf * 0.  */
     92 #ifndef FP_EX_INVALID_IMZ
     93 # define FP_EX_INVALID_IMZ	0
     94 #endif
     95 /* fma (Inf, 0, c).  */
     96 #ifndef FP_EX_INVALID_IMZ_FMA
     97 # define FP_EX_INVALID_IMZ_FMA	0
     98 #endif
     99 /* Inf - Inf.  */
    100 #ifndef FP_EX_INVALID_ISI
    101 # define FP_EX_INVALID_ISI	0
    102 #endif
    103 /* 0 / 0.  */
    104 #ifndef FP_EX_INVALID_ZDZ
    105 # define FP_EX_INVALID_ZDZ	0
    106 #endif
    107 /* Inf / Inf.  */
    108 #ifndef FP_EX_INVALID_IDI
    109 # define FP_EX_INVALID_IDI	0
    110 #endif
    111 /* sqrt (negative).  */
    112 #ifndef FP_EX_INVALID_SQRT
    113 # define FP_EX_INVALID_SQRT	0
    114 #endif
    115 /* Invalid conversion to integer.  */
    116 #ifndef FP_EX_INVALID_CVI
    117 # define FP_EX_INVALID_CVI	0
    118 #endif
    119 /* Invalid comparison.  */
    120 #ifndef FP_EX_INVALID_VC
    121 # define FP_EX_INVALID_VC	0
    122 #endif
    123 
    124 /* _FP_STRUCT_LAYOUT may be defined as an attribute to determine the
    125    struct layout variant used for structures where bit-fields are used
    126    to access specific parts of binary floating-point numbers.  This is
    127    required for systems where the default ABI uses struct layout with
    128    differences in how consecutive bit-fields are laid out from the
    129    default expected by soft-fp.  */
    130 #ifndef _FP_STRUCT_LAYOUT
    131 # define _FP_STRUCT_LAYOUT
    132 #endif
    133 
    134 #ifdef _FP_DECL_EX
    135 # define FP_DECL_EX					\
    136   int _fex = 0;						\
    137   _FP_DECL_EX
    138 #else
    139 # define FP_DECL_EX int _fex = 0
    140 #endif
    141 
    142 /* Initialize any machine-specific state used in FP_ROUNDMODE,
    143    FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS.  */
    144 #ifndef FP_INIT_ROUNDMODE
    145 # define FP_INIT_ROUNDMODE do {} while (0)
    146 #endif
    147 
    148 /* Initialize any machine-specific state used in
    149    FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS.  */
    150 #ifndef FP_INIT_TRAPPING_EXCEPTIONS
    151 # define FP_INIT_TRAPPING_EXCEPTIONS FP_INIT_ROUNDMODE
    152 #endif
    153 
    154 /* Initialize any machine-specific state used in
    155    FP_HANDLE_EXCEPTIONS.  */
    156 #ifndef FP_INIT_EXCEPTIONS
    157 # define FP_INIT_EXCEPTIONS FP_INIT_TRAPPING_EXCEPTIONS
    158 #endif
    159 
    160 #ifndef FP_HANDLE_EXCEPTIONS
    161 # define FP_HANDLE_EXCEPTIONS do {} while (0)
    162 #endif
    163 
    164 /* Whether to flush subnormal inputs to zero with the same sign.  */
    165 #ifndef FP_DENORM_ZERO
    166 # define FP_DENORM_ZERO 0
    167 #endif
    168 
    169 #ifndef FP_INHIBIT_RESULTS
    170 /* By default we write the results always.
    171    sfp-machine may override this and e.g.
    172    check if some exceptions are unmasked
    173    and inhibit it in such a case.  */
    174 # define FP_INHIBIT_RESULTS 0
    175 #endif
    176 
    177 #define FP_SET_EXCEPTION(ex)				\
    178   _fex |= (ex)
    179 
    180 #define FP_CUR_EXCEPTIONS				\
    181   (_fex)
    182 
    183 #ifndef FP_TRAPPING_EXCEPTIONS
    184 # define FP_TRAPPING_EXCEPTIONS 0
    185 #endif
    186 
    187 /* A file using soft-fp may define FP_NO_EXCEPTIONS before including
    188    soft-fp.h to indicate that, although a macro used there could raise
    189    exceptions, or do rounding and potentially thereby raise
    190    exceptions, for some arguments, for the particular arguments used
    191    in that file no exceptions or rounding can occur.  Such a file
    192    should not itself use macros relating to handling exceptions and
    193    rounding modes; this is only for indirect uses (in particular, in
    194    _FP_FROM_INT and the macros it calls).  */
    195 #ifdef FP_NO_EXCEPTIONS
    196 
    197 # undef FP_SET_EXCEPTION
    198 # define FP_SET_EXCEPTION(ex) do {} while (0)
    199 
    200 # undef FP_CUR_EXCEPTIONS
    201 # define FP_CUR_EXCEPTIONS 0
    202 
    203 # undef FP_TRAPPING_EXCEPTIONS
    204 # define FP_TRAPPING_EXCEPTIONS 0
    205 
    206 # undef FP_ROUNDMODE
    207 # define FP_ROUNDMODE FP_RND_ZERO
    208 
    209 # undef _FP_TININESS_AFTER_ROUNDING
    210 # define _FP_TININESS_AFTER_ROUNDING 0
    211 
    212 #endif
    213 
    214 /* A file using soft-fp may define FP_NO_EXACT_UNDERFLOW before
    215    including soft-fp.h to indicate that, although a macro used there
    216    could allow for the case of exact underflow requiring the underflow
    217    exception to be raised if traps are enabled, for the particular
    218    arguments used in that file no exact underflow can occur.  */
    219 #ifdef FP_NO_EXACT_UNDERFLOW
    220 # undef FP_TRAPPING_EXCEPTIONS
    221 # define FP_TRAPPING_EXCEPTIONS 0
    222 #endif
    223 
    224 #define _FP_ROUND_NEAREST(wc, X)				\
    225   do								\
    226     {								\
    227       if ((_FP_FRAC_LOW_##wc (X) & 15) != _FP_WORK_ROUND)	\
    228 	_FP_FRAC_ADDI_##wc (X, _FP_WORK_ROUND);			\
    229     }								\
    230   while (0)
    231 
    232 #define _FP_ROUND_ZERO(wc, X)		(void) 0
    233 
    234 #define _FP_ROUND_PINF(wc, X)				\
    235   do							\
    236     {							\
    237       if (!X##_s && (_FP_FRAC_LOW_##wc (X) & 7))	\
    238 	_FP_FRAC_ADDI_##wc (X, _FP_WORK_LSB);		\
    239     }							\
    240   while (0)
    241 
    242 #define _FP_ROUND_MINF(wc, X)			\
    243   do						\
    244     {						\
    245       if (X##_s && (_FP_FRAC_LOW_##wc (X) & 7))	\
    246 	_FP_FRAC_ADDI_##wc (X, _FP_WORK_LSB);	\
    247     }						\
    248   while (0)
    249 
    250 #define _FP_ROUND(wc, X)			\
    251   do						\
    252     {						\
    253       if (_FP_FRAC_LOW_##wc (X) & 7)		\
    254 	{					\
    255 	  FP_SET_EXCEPTION (FP_EX_INEXACT);	\
    256 	  switch (FP_ROUNDMODE)			\
    257 	    {					\
    258 	    case FP_RND_NEAREST:		\
    259 	      _FP_ROUND_NEAREST (wc, X);	\
    260 	      break;				\
    261 	    case FP_RND_ZERO:			\
    262 	      _FP_ROUND_ZERO (wc, X);		\
    263 	      break;				\
    264 	    case FP_RND_PINF:			\
    265 	      _FP_ROUND_PINF (wc, X);		\
    266 	      break;				\
    267 	    case FP_RND_MINF:			\
    268 	      _FP_ROUND_MINF (wc, X);		\
    269 	      break;				\
    270 	    }					\
    271 	}					\
    272     }						\
    273   while (0)
    274 
    275 #define FP_CLS_NORMAL		0
    276 #define FP_CLS_ZERO		1
    277 #define FP_CLS_INF		2
    278 #define FP_CLS_NAN		3
    279 
    280 #define _FP_CLS_COMBINE(x, y)	(((x) << 2) | (y))
    281 
    282 #include "op-1.h"
    283 #include "op-2.h"
    284 #include "op-4.h"
    285 #include "op-8.h"
    286 #include "op-common.h"
    287 
    288 /* Sigh.  Silly things longlong.h needs.  */
    289 #define UWtype		_FP_W_TYPE
    290 #define W_TYPE_SIZE	_FP_W_TYPE_SIZE
    291 
    292 typedef int QItype __attribute__ ((mode (QI)));
    293 typedef int SItype __attribute__ ((mode (SI)));
    294 typedef int DItype __attribute__ ((mode (DI)));
    295 typedef unsigned int UQItype __attribute__ ((mode (QI)));
    296 typedef unsigned int USItype __attribute__ ((mode (SI)));
    297 typedef unsigned int UDItype __attribute__ ((mode (DI)));
    298 #if _FP_W_TYPE_SIZE == 32
    299 typedef unsigned int UHWtype __attribute__ ((mode (HI)));
    300 #elif _FP_W_TYPE_SIZE == 64
    301 typedef USItype UHWtype;
    302 #endif
    303 
    304 #ifndef CMPtype
    305 # define CMPtype	int
    306 #endif
    307 
    308 #define SI_BITS		(__CHAR_BIT__ * (int) sizeof (SItype))
    309 #define DI_BITS		(__CHAR_BIT__ * (int) sizeof (DItype))
    310 
    311 #ifndef umul_ppmm
    312 # ifdef _LIBC
    313 #  include <stdlib/longlong.h>
    314 # else
    315 #  include "longlong.h"
    316 # endif
    317 #endif
    318 
    319 #ifdef _LIBC
    320 # include <stdlib.h>
    321 #else
    322 extern void abort (void);
    323 #endif
    324 
    325 #endif
    326