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