zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

fenv.h (19641B) - Raw


      1 /*
      2  * Copyright (c) 2002-2013 Apple Computer, Inc. All rights reserved.
      3  *
      4  * @APPLE_LICENSE_HEADER_START@
      5  * 
      6  * The contents of this file constitute Original Code as defined in and
      7  * are subject to the Apple Public Source License Version 1.1 (the
      8  * "License").  You may not use this file except in compliance with the
      9  * License.  Please obtain a copy of the License at
     10  * http://www.apple.com/publicsource and read it before using this file.
     11  * 
     12  * This Original Code and all software distributed under the License are
     13  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
     14  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
     15  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
     17  * License for the specific language governing rights and limitations
     18  * under the License.
     19  * 
     20  * @APPLE_LICENSE_HEADER_END@
     21  */
     22  
     23 /******************************************************************************
     24  *                                                                            *
     25  *  File:  fenv.h                                                             *
     26  *                                                                            *
     27  *  Contains: typedefs and prototypes for C99 floating point environment.     *
     28  *                                                                            *
     29  *  A collection of functions designed to provide access to the floating      *
     30  *  point environment for numerical programming. It is compliant with the     *
     31  *  floating-point requirements in C99.                                       *
     32  *                                                                            *
     33  *  The file <fenv.h> declares many functions in support of numerical         *
     34  *  programming. Programs that test flags or run under non-default mode       *
     35  *  must do so under the effect of an enabling "fenv_access" pragma:          *
     36  *                                                                            *
     37  *      #pragma STDC FENV_ACCESS on                                           *
     38  *                                                                            *
     39  ******************************************************************************/
     40 
     41 #ifndef __FENV_H__
     42 #define __FENV_H__
     43 
     44 #ifdef __cplusplus
     45 extern "C" {
     46 #endif
     47     
     48 /******************************************************************************
     49  *                                                                            *
     50  *  Architecture-specific types and macros.                                   *
     51  *                                                                            *
     52  *      fenv_t          a type for representing the entire floating-point     *
     53  *                      environment in a single object.                       *
     54  *                                                                            *
     55  *      fexcept_t       a type for representing the floating-point            *
     56  *                      exception flag state collectively.                    *
     57  *                                                                            *
     58  *      FE_INEXACT      macros representing the various floating-point        *
     59  *      FE_UNDERFLOW    exceptions.                                           *
     60  *      FE_OVERFLOW                                                           *
     61  *      FE_DIVBYZERO                                                          *
     62  *      FE_INVALID                                                            *
     63  *      FE_ALL_EXCEPT                                                         *
     64  *                                                                            *
     65  *      FE_TONEAREST    macros representing the various floating-point        *
     66  *      FE_UPWARD       rounding modes                                        *
     67  *      FE_DOWNWARD                                                           *
     68  *      FE_TOWARDZERO                                                         *
     69  *                                                                            *
     70  *      FE_DFL_ENV      a macro expanding to a pointer to an object           *
     71  *                      representing the default floating-point environemnt   *
     72  *                                                                            *
     73  ******************************************************************************/
     74     
     75 /******************************************************************************
     76  *  ARM definitions of architecture-specific types and macros.                *
     77  ******************************************************************************/
     78      
     79 #if defined __arm__ && !defined __SOFTFP__
     80      
     81 typedef struct {
     82     unsigned int            __fpscr;    
     83     unsigned int            __reserved0;
     84     unsigned int            __reserved1;
     85     unsigned int            __reserved2;
     86 } fenv_t;
     87 
     88 typedef unsigned short fexcept_t;
     89     
     90 #define FE_INEXACT          0x0010
     91 #define FE_UNDERFLOW        0x0008
     92 #define FE_OVERFLOW         0x0004
     93 #define FE_DIVBYZERO        0x0002
     94 #define FE_INVALID          0x0001
     95 /*  FE_FLUSHTOZERO
     96     An ARM-specific flag that is raised when a denormal is flushed to zero.
     97     This is also called the "input denormal exception"                        */
     98 #define FE_FLUSHTOZERO      0x0080 
     99 #define FE_ALL_EXCEPT       0x009f
    100     
    101 #define FE_TONEAREST        0x00000000
    102 #define FE_UPWARD           0x00400000
    103 #define FE_DOWNWARD         0x00800000
    104 #define FE_TOWARDZERO       0x00C00000
    105 
    106 /*  Masks for values that may be controlled in the FPSCR.  Modifying any other
    107     bits invokes undefined behavior.                                          */
    108 enum {
    109     __fpscr_trap_invalid   = 0x00000100,
    110     __fpscr_trap_divbyzero = 0x00000200,
    111     __fpscr_trap_overflow  = 0x00000400,
    112     __fpscr_trap_underflow = 0x00000800,
    113     __fpscr_trap_inexact   = 0x00001000,
    114     __fpscr_trap_denormal  = 0x00008000,
    115     __fpscr_flush_to_zero  = 0x01000000,
    116     __fpscr_default_nan    = 0x02000000,
    117     __fpscr_saturation     = 0x08000000,
    118 };
    119 
    120 extern const fenv_t _FE_DFL_ENV;
    121 #define FE_DFL_ENV &_FE_DFL_ENV
    122     
    123 /******************************************************************************
    124  *  ARM64 definitions of architecture-specific types and macros.              *
    125  ******************************************************************************/
    126     
    127 #elif defined __arm64__
    128     
    129 typedef struct {
    130     unsigned long long      __fpsr;
    131     unsigned long long      __fpcr;
    132 } fenv_t;
    133     
    134 typedef unsigned short fexcept_t;
    135     
    136 #define FE_INEXACT          0x0010
    137 #define FE_UNDERFLOW        0x0008
    138 #define FE_OVERFLOW         0x0004
    139 #define FE_DIVBYZERO        0x0002
    140 #define FE_INVALID          0x0001
    141 /*  FE_FLUSHTOZERO
    142     An ARM-specific flag that is raised when a denormal is flushed to zero.
    143     This is also called the "input denormal exception"                        */
    144 #define FE_FLUSHTOZERO      0x0080 
    145 #define FE_ALL_EXCEPT       0x009f
    146     
    147 #define FE_TONEAREST        0x00000000
    148 #define FE_UPWARD           0x00400000
    149 #define FE_DOWNWARD         0x00800000
    150 #define FE_TOWARDZERO       0x00C00000
    151     
    152 /*  Masks for values that may be controlled in the FPCR.  Modifying any other
    153     bits invokes undefined behavior.                                          */
    154 enum {
    155     __fpcr_trap_invalid   = 0x00000100,
    156     __fpcr_trap_divbyzero = 0x00000200,
    157     __fpcr_trap_overflow  = 0x00000400,
    158     __fpcr_trap_underflow = 0x00000800,
    159     __fpcr_trap_inexact   = 0x00001000,
    160     __fpcr_trap_denormal  = 0x00008000,
    161     __fpcr_flush_to_zero  = 0x01000000,
    162 };
    163 
    164 /*  Mask for the QC bit of the FPSR                                           */
    165 enum { __fpsr_saturation  = 0x08000000 };
    166     
    167 extern const fenv_t _FE_DFL_ENV;
    168 #define FE_DFL_ENV &_FE_DFL_ENV
    169 
    170 /*  FE_DFL_DISABLE_DENORMS_ENV
    171  
    172     A pointer to a fenv_t object with the default floating-point state modified
    173     to set the FZ (flush to zero) bit in the FPCR.  When using this environment
    174     denormals encountered by floating-point calculations will be treated as
    175     zero.  Denormal results of floating-point operations will also be treated
    176     as zero.  This calculation mode is not IEEE-754 compliant, but it may
    177     prevent lengthy stalls that occur in code that encounters denormals.  It is
    178     suggested that you do not use this mode unless you have established that
    179     denormals are the source of measurable performance problems.
    180  
    181     Note that the math library, and other system libraries, are not guaranteed
    182     to do the right thing if called in this mode.  Edge cases may be incorrect.
    183     Use at your own risk.                                                     */
    184 extern const fenv_t _FE_DFL_DISABLE_DENORMS_ENV;
    185 #define FE_DFL_DISABLE_DENORMS_ENV &_FE_DFL_DISABLE_DENORMS_ENV
    186     
    187 /******************************************************************************
    188  *  x86 definitions of architecture-specific types and macros.                *
    189  ******************************************************************************/
    190     
    191 #elif defined __i386__ || defined __x86_64__
    192 
    193 typedef struct {
    194     unsigned short          __control;      /* x87 control word               */
    195     unsigned short          __status;       /* x87 status word                */
    196     unsigned int            __mxcsr;        /* SSE status/control register    */
    197     char                    __reserved[8];  /* Reserved for future expansion  */   
    198 } fenv_t;
    199 
    200 typedef unsigned short fexcept_t;
    201     
    202 #define FE_INEXACT          0x0020
    203 #define FE_UNDERFLOW        0x0010
    204 #define FE_OVERFLOW         0x0008
    205 #define FE_DIVBYZERO        0x0004
    206 #define FE_INVALID          0x0001
    207 /*  FE_DENORMALOPERAND
    208     An Intel-specific flag that is raised when an operand to a floating-point
    209     arithmetic operation is denormal, or a single- or double-precision denormal
    210     value is loaded on the x87 stack.  This flag is not raised by SSE
    211     arithmetic when the DAZ control bit is set.                               */
    212 #define FE_DENORMALOPERAND  0x0002
    213 #define FE_ALL_EXCEPT       0x003f
    214 
    215 #define FE_TONEAREST        0x0000
    216 #define FE_DOWNWARD         0x0400
    217 #define FE_UPWARD           0x0800
    218 #define FE_TOWARDZERO       0x0c00
    219 
    220 extern const fenv_t _FE_DFL_ENV;
    221 #define FE_DFL_ENV &_FE_DFL_ENV
    222 
    223 /*  FE_DFL_DISABLE_SSE_DENORMS_ENV
    224  
    225     A pointer to a fenv_t object with the default floating-point state modifed
    226     to set the DAZ and FZ bits in the SSE status/control register.  When using
    227     this environment, denormals encountered by SSE based calculation (which
    228     normally should be all single and double precision scalar floating point
    229     calculations, and all SSE/SSE2/SSE3 computation) will be treated as zero.
    230     Calculation results that are denormals will also be truncated to zero.
    231     This calculation mode is not IEEE-754 compliant, but may prevent lengthy
    232     stalls that occur in code that encounters denormals. It is suggested that
    233     you do not use this mode unless you have established that denormals are
    234     causing trouble for your code. Please use wisely.
    235     
    236     CAUTION: The math library currently is not architected to do the right
    237     thing in the face of DAZ + FZ mode.  For example, ceil( +denormal) might
    238     return +denormal rather than 1.0 in some versions of MacOS X. In some
    239     circumstances this may lead to unexpected application behavior. Use at
    240     your own risk.
    241  
    242     It is not possible to disable denormal stalls for calculations performed
    243     on the x87 FPU                                                            */
    244 extern const fenv_t _FE_DFL_DISABLE_SSE_DENORMS_ENV;
    245 #define FE_DFL_DISABLE_SSE_DENORMS_ENV  &_FE_DFL_DISABLE_SSE_DENORMS_ENV
    246 
    247 /******************************************************************************
    248  *  Totally generic definitions and macros if we don't know anything about    *
    249  *  the target platform, or if the platform does not have hardware floating-  *
    250  *  point support.                                                            *
    251  ******************************************************************************/
    252 
    253 #elif defined __riscv
    254 
    255 typedef struct {
    256     unsigned int            __fpsr;
    257     unsigned int            __fpcr;
    258 } fenv_t;
    259 
    260 typedef unsigned short fexcept_t;
    261 
    262 #define FE_INEXACT          (1)
    263 #define FE_UNDERFLOW        (1 << 1)
    264 #define FE_OVERFLOW         (1 << 2)
    265 #define FE_DIVBYZERO        (1 << 3)
    266 #define FE_INVALID          (1 << 4)
    267 
    268 #define FE_ALL_EXCEPT       (31)
    269 
    270 #define FE_TONEAREST                (0)
    271 #define FE_TOWARDZERO               (1 << 5)
    272 #define FE_DOWNWARD                 (2 << 5)
    273 #define FE_UPWARD                   (3 << 5)
    274 #define FE_TONEAREST_MAX_MAGNITUDE  (4 << 5)
    275 // Reserved: (5 << 5)
    276 // Reserved: (6 << 5)
    277 #define FE_DYNAMIC                  (7 << 5)
    278     
    279 #else /* Unknown architectures */
    280 
    281 typedef int fenv_t;
    282 typedef unsigned short fexcept_t;
    283 #define FE_ALL_EXCEPT       0
    284 #define FE_TONEAREST        0
    285 extern const fenv_t _FE_DFL_ENV;
    286 #define FE_DFL_ENV &_FE_DFL_ENV
    287 
    288 #endif
    289 
    290 /******************************************************************************
    291  *  The following functions provide high level access to the exception flags. *  
    292  *  The "int" input argument can be constructed by bitwise ORs of the         *
    293  *  exception macros: for example: FE_OVERFLOW | FE_INEXACT.                  *
    294  *                                                                            *
    295  *  The function "feclearexcept" clears the supported floating point          *
    296  *  exceptions represented by its argument.                                   *
    297  *                                                                            *
    298  *  The function "fegetexceptflag" stores a implementation-defined            *
    299  *  representation of the states of the floating-point status flags indicated *
    300  *  by its integer argument excepts in the object pointed to by the argument, * 
    301  *  flagp.                                                                    *
    302  *                                                                            *
    303  *  The function "feraiseexcept" raises the supported floating-point          *
    304  *  exceptions represented by its argument. The order in which these          *
    305  *  floating-point exceptions are raised is unspecified.                      *
    306  *                                                                            *
    307  *  The function "fesetexceptflag" sets or clears the floating point status   *
    308  *  flags indicated by the argument excepts to the states stored in the       *
    309  *  object pointed to by flagp. The value of the *flagp shall have been set   *
    310  *  by a previous call to fegetexceptflag whose second argument represented   *
    311  *  at least those floating-point exceptions represented by the argument      *
    312  *  excepts. This function does not raise floating-point exceptions; it just  *
    313  *  sets the state of the flags.                                              *
    314  *                                                                            *
    315  *  The function "fetestexcept" determines which of the specified subset of   *
    316  *  the floating-point exception flags are currently set.  The excepts        *
    317  *  argument specifies the floating-point status flags to be queried. This    *
    318  *  function returns the value of the bitwise OR of the floating-point        *
    319  *  exception macros corresponding to the currently set floating-point        *
    320  *  exceptions included in excepts.                                           *
    321  ******************************************************************************/
    322 
    323 extern int feclearexcept(int /* excepts */);
    324 extern int fegetexceptflag(fexcept_t * /* flagp */, int /* excepts */);
    325 extern int feraiseexcept(int /* excepts */);
    326 extern int fesetexceptflag(const fexcept_t * /* flagp */, int /* excepts */);
    327 extern int fetestexcept(int /* excepts */);
    328 
    329 /******************************************************************************
    330  *  The following functions provide control of rounding direction modes.      *
    331  *                                                                            *
    332  *  The function "fegetround" returns the value of the rounding direction     *
    333  *  macro which represents the current rounding direction, or a negative      *
    334  *  if there is no such rounding direction macro or the current rounding      *
    335  *  direction is not determinable.                                            *
    336  *                                                                            *
    337  *  The function "fesetround" establishes the rounding direction represented  *
    338  *  by its argument "round". If the argument is not equal to the value of a   *
    339  *  rounding direction macro, the rounding direction is not changed.  It      *
    340  *  returns zero if and only if the argument is equal to a rounding           *
    341  *  direction macro.                                                          *
    342  ******************************************************************************/
    343     
    344 extern int fegetround(void);
    345 extern int fesetround(int /* round */);
    346 
    347 /******************************************************************************
    348  *  The following functions manage the floating-point environment, exception  *
    349  *  flags and dynamic modes, as one entity.                                   *
    350  *                                                                            *
    351  *  The fegetenv function stores the current floating-point enviornment in    *
    352  *  the object pointed to by envp.                                            *
    353  *                                                                            *
    354  *  The feholdexcept function saves the current floating-point environment in *
    355  *  the object pointed to by envp, clears the floating-point status flags,    *
    356  *  and then installs a non-stop (continue on floating-point exceptions)      *
    357  *  mode, if available, for all floating-point exceptions. The feholdexcept   *
    358  *  function returns zero if and only if non-stop floating-point exceptions   *
    359  *  handling was successfully installed.                                      *
    360  *                                                                            *
    361  *  The fesetnv function establishes the floating-point environment           *
    362  *  represented by the object pointed to by envp. The argument envp shall     *
    363  *  point to an object set by a call to fegetenv or feholdexcept, or equal to *
    364  *  a floating-point environment macro to be C99 standard compliant and       *
    365  *  portable to other architectures. Note that fesetnv merely installs the    *
    366  *  state of the floating-point status flags represented through its          *
    367  *  argument, and does not raise these floating-point exceptions.             *
    368  *                                                                            *
    369  *  The feupdateenv function saves the currently raised floating-point        *
    370  *  exceptions in its automatic storage, installs the floating-point          *
    371  *  environment represented by the object pointed to by envp, and then raises *
    372  *  the saved floating-point exceptions. The argument envp shall point to an  *
    373  *  object set by a call to feholdexcept or fegetenv or equal a               *
    374  *  floating-point environment macro.                                         *
    375  ******************************************************************************/
    376     
    377 extern int fegetenv(fenv_t * /* envp */);
    378 extern int feholdexcept(fenv_t * /* envp */);
    379 extern int fesetenv(const fenv_t * /* envp */);
    380 extern int feupdateenv(const fenv_t * /* envp */);
    381 
    382 #ifdef __cplusplus
    383 }
    384 #endif
    385 
    386 #endif /* __FENV_H__ */
    387