(root)/
glibc-2.38/
sysdeps/
generic/
get-rounding-mode.h
       1  /* Determine floating-point rounding mode within libc.  Generic version.
       2     Copyright (C) 2012-2023 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     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #ifndef _GET_ROUNDING_MODE_H
      20  #define _GET_ROUNDING_MODE_H	1
      21  
      22  #include <fpu_control.h>
      23  #include <stdlib.h>
      24  
      25  /* Define values for FE_* modes not defined for this architecture.  */
      26  #ifdef FE_DOWNWARD
      27  # define ORIG_FE_DOWNWARD FE_DOWNWARD
      28  #else
      29  # define ORIG_FE_DOWNWARD 0
      30  #endif
      31  #ifdef FE_TONEAREST
      32  # define ORIG_FE_TONEAREST FE_TONEAREST
      33  #else
      34  # define ORIG_FE_TONEAREST 0
      35  #endif
      36  #ifdef FE_TOWARDZERO
      37  # define ORIG_FE_TOWARDZERO FE_TOWARDZERO
      38  #else
      39  # define ORIG_FE_TOWARDZERO 0
      40  #endif
      41  #ifdef FE_UPWARD
      42  # define ORIG_FE_UPWARD FE_UPWARD
      43  #else
      44  # define ORIG_FE_UPWARD 0
      45  #endif
      46  #define FE_CONSTRUCT_DISTINCT_VALUE(X, Y, Z) \
      47    ((((X) & 1) | ((Y) & 2) | ((Z) & 4)) ^ 7)
      48  #ifndef FE_DOWNWARD
      49  # define FE_DOWNWARD FE_CONSTRUCT_DISTINCT_VALUE (ORIG_FE_TONEAREST,	\
      50  						  ORIG_FE_TOWARDZERO,	\
      51  						  ORIG_FE_UPWARD)
      52  #endif
      53  #ifndef FE_TONEAREST
      54  # define FE_TONEAREST FE_CONSTRUCT_DISTINCT_VALUE (FE_DOWNWARD,		\
      55  						   ORIG_FE_TOWARDZERO,	\
      56  						   ORIG_FE_UPWARD)
      57  #endif
      58  #ifndef FE_TOWARDZERO
      59  # define FE_TOWARDZERO FE_CONSTRUCT_DISTINCT_VALUE (FE_DOWNWARD,	\
      60  						    FE_TONEAREST,	\
      61  						    ORIG_FE_UPWARD)
      62  #endif
      63  #ifndef FE_UPWARD
      64  # define FE_UPWARD FE_CONSTRUCT_DISTINCT_VALUE (FE_DOWNWARD,	\
      65  						FE_TONEAREST,	\
      66  						FE_TOWARDZERO)
      67  #endif
      68  
      69  /* Return the floating-point rounding mode.  */
      70  
      71  static inline int
      72  get_rounding_mode (void)
      73  {
      74  #if (defined _FPU_RC_DOWN			\
      75       || defined _FPU_RC_NEAREST			\
      76       || defined _FPU_RC_ZERO			\
      77       || defined _FPU_RC_UP)
      78    fpu_control_t fc;
      79    const fpu_control_t mask = (0
      80  # ifdef _FPU_RC_DOWN
      81  			      | _FPU_RC_DOWN
      82  # endif
      83  # ifdef _FPU_RC_NEAREST
      84  			      | _FPU_RC_NEAREST
      85  # endif
      86  # ifdef _FPU_RC_ZERO
      87  			      | _FPU_RC_ZERO
      88  # endif
      89  # ifdef _FPU_RC_UP
      90  			      | _FPU_RC_UP
      91  # endif
      92  			      );
      93  
      94    _FPU_GETCW (fc);
      95    switch (fc & mask)
      96      {
      97  # ifdef _FPU_RC_DOWN
      98      case _FPU_RC_DOWN:
      99        return FE_DOWNWARD;
     100  # endif
     101  
     102  # ifdef _FPU_RC_NEAREST
     103      case _FPU_RC_NEAREST:
     104        return FE_TONEAREST;
     105  # endif
     106  
     107  # ifdef _FPU_RC_ZERO
     108      case _FPU_RC_ZERO:
     109        return FE_TOWARDZERO;
     110  # endif
     111  
     112  # ifdef _FPU_RC_UP
     113      case _FPU_RC_UP:
     114        return FE_UPWARD;
     115  # endif
     116  
     117      default:
     118        abort ();
     119      }
     120  #else
     121    return FE_TONEAREST;
     122  #endif
     123  }
     124  
     125  #endif /* get-rounding-mode.h */