2 * D header file for C99.
4 * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_fenv.h.html, _fenv.h)
6 * Copyright: Copyright Sean Kelly 2005 - 2009.
7 * License: Distributed under the
8 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
9 * (See accompanying file LICENSE)
11 * Source: $(DRUNTIMESRC core/stdc/_fenv.d)
12 * Standards: ISO/IEC 9899:1999 (E)
15 module core.stdc.fenv;
23 else version (WatchOS)
31 version (ARM) version = ARM_Any;
32 version (AArch64) version = ARM_Any;
33 version (HPPA) version = HPPA_Any;
34 version (MIPS32) version = MIPS_Any;
35 version (MIPS64) version = MIPS_Any;
36 version (PPC) version = PPC_Any;
37 version (PPC64) version = PPC_Any;
38 version (RISCV32) version = RISCV_Any;
39 version (RISCV64) version = RISCV_Any;
40 version (S390) version = IBMZ_Any;
41 version (SPARC) version = SPARC_Any;
42 version (SPARC64) version = SPARC_Any;
43 version (SystemZ) version = IBMZ_Any;
44 version (X86) version = X86_Any;
45 version (X86_64) version = X86_Any;
49 version (CRuntime_Glibc)
54 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h
59 ushort __control_word;
69 ushort __data_selector;
73 alias fexcept_t = ushort;
75 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h
80 ushort __control_word;
90 ushort __data_selector;
95 alias fexcept_t = ushort;
97 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/hppa/bits/fenv.h
98 else version (HPPA_Any)
106 alias fexcept_t = uint;
108 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mips/bits/fenv.h
109 else version (MIPS_Any)
113 uint __fp_control_register;
116 alias fexcept_t = ushort;
118 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/aarch64/bits/fenv.h
119 else version (AArch64)
127 alias fexcept_t = uint;
129 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/bits/fenv.h
137 alias fexcept_t = uint;
139 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/bits/fenv.h
140 else version (PPC_Any)
142 alias fenv_t = double;
143 alias fexcept_t = uint;
145 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/riscv/bits/fenv.h
146 else version (RISCV_Any)
149 alias fexcept_t = uint;
151 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/fpu/bits/fenv.h
152 else version (SPARC_Any)
154 import core.stdc.config : c_ulong;
156 alias fenv_t = c_ulong;
157 alias fexcept_t = c_ulong;
159 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/s390/fpu/bits/fenv.h
160 else version (IBMZ_Any)
168 alias fexcept_t = uint;
172 static assert(0, "Unimplemented architecture");
175 else version (CRuntime_DigitalMars)
184 alias fexcept_t = int;
186 else version (CRuntime_Microsoft)
194 alias fexcept_t = uint;
196 else version (Darwin)
201 alias uint fexcept_t;
203 version (LittleEndian)
213 alias ushort fexcept_t;
216 else version (FreeBSD)
228 alias ushort fexcept_t;
230 else version (NetBSD)
238 uint control; /* Control word register */
239 uint status; /* Status word register */
240 uint tag; /* Tag word register */
241 uint[4] others; /* EIP, Pointer Selector, etc */
245 uint mxcsr; /* Control and status register */
254 ushort control; /* Control word register */
256 ushort status; /* Status word register */
258 ushort tag; /* Tag word register */
260 uint[4] others; /* EIP, Pointer Selector, etc */
263 uint mxcsr; /* Control and status register */
268 alias uint fexcept_t;
270 else version (OpenBSD)
284 alias fexcept_t = uint;
286 else version (DragonFlyBSD)
302 alias uint fexcept_t;
304 else version (CRuntime_Bionic)
318 alias ushort fexcept_t;
323 alias uint fexcept_t;
325 else version (AArch64)
333 alias uint fexcept_t;
335 else version (X86_64)
351 alias uint fexcept_t;
355 static assert(false, "Architecture not supported.");
358 else version (Solaris)
360 import core.stdc.config : c_ulong;
362 enum FEX_NUM_EXC = 12;
367 void function() __handler;
372 fex_handler_t[FEX_NUM_EXC] __handler;
378 else version (CRuntime_Musl)
387 alias uint fexcept_t;
391 import core.stdc.config : c_ulong;
397 alias c_ulong fexcept_t;
399 else version (IBMZ_Any)
402 alias uint fexcept_t;
404 else version (MIPS_Any)
410 alias ushort fexcept_t;
412 else version (PPC_Any)
415 alias uint fexcept_t;
417 else version (X86_Any)
421 ushort __control_word;
423 ushort __status_word;
428 ushort __cs_selector;
431 ushort __data_selector;
436 alias ushort fexcept_t;
440 static assert(false, "Architecture not supported.");
443 else version (CRuntime_UClibc)
449 ushort __control_word;
451 ushort __status_word;
456 ushort __cs_selector;
459 ushort __data_selector;
463 alias fexcept_t = ushort;
465 else version (X86_64)
469 ushort __control_word;
471 ushort __status_word;
476 ushort __cs_selector;
479 ushort __data_selector;
484 alias fexcept_t = ushort;
486 else version (MIPS32)
490 uint __fp_control_register;
493 alias fexcept_t = ushort;
502 alias fexcept_t = uint;
506 static assert(false, "Architecture not supported.");
511 static assert( false, "Unsupported platform" );
514 version (CRuntime_Microsoft)
519 FE_UNDERFLOW = 2, ///
521 FE_DIVBYZERO = 8, ///
522 FE_INVALID = 0x10, ///
523 FE_ALL_EXCEPT = 0x1F, ///
524 FE_TONEAREST = 0, ///
525 FE_UPWARD = 0x100, ///
526 FE_DOWNWARD = 0x200, ///
527 FE_TOWARDZERO = 0x300, ///
530 else version (Solaris)
549 FE_ALL_EXCEPT = 0x1f,
553 else version (X86_Any)
570 FE_ALL_EXCEPT = 0x3d,
575 static assert(0, "Unimplemented architecture");
582 // Define bits representing the exception.
585 FE_INVALID = 0x01, ///
586 FE_DENORMAL = 0x02, /// non-standard
587 FE_DIVBYZERO = 0x04, ///
588 FE_OVERFLOW = 0x08, ///
589 FE_UNDERFLOW = 0x10, ///
590 FE_INEXACT = 0x20, ///
591 FE_ALL_EXCEPT = 0x3F, ///
594 // The ix87 FPU supports all of the four defined rounding modes.
597 FE_TONEAREST = 0, ///
598 FE_DOWNWARD = 0x400, ///
599 FE_UPWARD = 0x800, ///
600 FE_TOWARDZERO = 0xC00, ///
603 else version (X86_64)
605 // Define bits representing the exception.
608 FE_INVALID = 0x01, ///
609 FE_DENORMAL = 0x02, /// non-standard
610 FE_DIVBYZERO = 0x04, ///
611 FE_OVERFLOW = 0x08, ///
612 FE_UNDERFLOW = 0x10, ///
613 FE_INEXACT = 0x20, ///
614 FE_ALL_EXCEPT = 0x3F, ///
617 // The ix87 FPU supports all of the four defined rounding modes.
620 FE_TONEAREST = 0, ///
621 FE_DOWNWARD = 0x400, ///
622 FE_UPWARD = 0x800, ///
623 FE_TOWARDZERO = 0xC00, ///
626 else version (ARM_Any)
628 // Define bits representing exceptions in the FPU status word.
632 FE_DIVBYZERO = 2, ///
634 FE_UNDERFLOW = 8, ///
636 FE_ALL_EXCEPT = 31, ///
639 // VFP supports all of the four defined rounding modes.
642 FE_TONEAREST = 0, ///
643 FE_UPWARD = 0x400000, ///
644 FE_DOWNWARD = 0x800000, ///
645 FE_TOWARDZERO = 0xC00000, ///
648 else version (HPPA_Any)
650 // Define bits representing the exception.
653 FE_INEXACT = 0x01, ///
654 FE_UNDERFLOW = 0x02, ///
655 FE_OVERFLOW = 0x04, ///
656 FE_DIVBYZERO = 0x08, ///
657 FE_INVALID = 0x10, ///
658 FE_ALL_EXCEPT = 0x1F, ///
661 // The HPPA FPU supports all of the four defined rounding modes.
664 FE_TONEAREST = 0x0, ///
665 FE_TOWARDZERO = 0x200, ///
666 FE_UPWARD = 0x400, ///
667 FE_DOWNWARD = 0x600, ///
670 else version (MIPS_Any)
672 // Define bits representing the exception.
675 FE_INEXACT = 0x04, ///
676 FE_UNDERFLOW = 0x08, ///
677 FE_OVERFLOW = 0x10, ///
678 FE_DIVBYZERO = 0x20, ///
679 FE_INVALID = 0x40, ///
680 FE_ALL_EXCEPT = 0x7C, ///
683 // The MIPS FPU supports all of the four defined rounding modes.
686 FE_TONEAREST = 0x0, ///
687 FE_TOWARDZERO = 0x1, ///
689 FE_DOWNWARD = 0x3, ///
692 else version (PPC_Any)
694 // Define bits representing the exception.
697 FE_INEXACT = 0x2000000, ///
698 FE_DIVBYZERO = 0x4000000, ///
699 FE_UNDERFLOW = 0x8000000, ///
700 FE_OVERFLOW = 0x10000000, ///
701 FE_INVALID = 0x20000000, ///
702 FE_INVALID_SNAN = 0x1000000, /// non-standard
703 FE_INVALID_ISI = 0x800000, /// non-standard
704 FE_INVALID_IDI = 0x400000, /// non-standard
705 FE_INVALID_ZDZ = 0x200000, /// non-standard
706 FE_INVALID_IMZ = 0x100000, /// non-standard
707 FE_INVALID_COMPARE = 0x80000, /// non-standard
708 FE_INVALID_SOFTWARE = 0x400, /// non-standard
709 FE_INVALID_SQRT = 0x200, /// non-standard
710 FE_INVALID_INTEGER_CONVERSION = 0x100, /// non-standard
711 FE_ALL_INVALID = 0x1F80700, /// non-standard
712 FE_ALL_EXCEPT = 0x3E000000, ///
715 // PowerPC chips support all of the four defined rounding modes.
718 FE_TONEAREST = 0, ///
719 FE_TOWARDZERO = 1, ///
724 else version (RISCV_Any)
726 // Define bits representing exceptions in the FPSR status word.
729 FE_INEXACT = 0x01, ///
730 FE_UNDERFLOW = 0x02, ///
731 FE_OVERFLOW = 0x04, ///
732 FE_DIVBYZERO = 0x08, ///
733 FE_INVALID = 0x10, ///
734 FE_ALL_EXCEPT = 0x1f, ///
737 // Define bits representing rounding modes in the FPCR Rmode field.
740 FE_TONEAREST = 0x0, ///
741 FE_TOWARDZERO = 0x1, ///
742 FE_DOWNWARD = 0x2, ///
746 else version (SPARC_Any)
748 // Define bits representing the exception.
751 FE_INVALID = 0x200, ///
752 FE_OVERFLOW = 0x100, ///
753 FE_UNDERFLOW = 0x80, ///
754 FE_DIVBYZERO = 0x40, ///
755 FE_INEXACT = 0x20, ///
756 FE_ALL_EXCEPT = 0x3E0, ///
759 // The Sparc FPU supports all of the four defined rounding modes.
762 FE_TONEAREST = 0x0, ///
763 FE_TOWARDZERO = 0x40000000, ///
764 FE_UPWARD = 0x80000000, ///
765 FE_DOWNWARD = 0xc0000000, ///
768 else version (IBMZ_Any)
770 // Define bits representing the exception.
773 FE_INVALID = 0x80, ///
774 FE_DIVBYZERO = 0x40, ///
775 FE_OVERFLOW = 0x20, ///
776 FE_UNDERFLOW = 0x10, ///
777 FE_INEXACT = 0x08, ///
778 FE_ALL_EXCEPT = 0xF8, ///
781 // SystemZ supports all of the four defined rounding modes.
784 FE_TONEAREST = 0x0, ///
785 FE_DOWNWARD = 0x3, ///
787 FE_TOWARDZERO = 0x1, ///
792 static assert(0, "Unimplemented architecture");
800 enum FE_DFL_ENV = cast(fenv_t*)(-1);
802 else version (CRuntime_DigitalMars)
804 private extern __gshared fenv_t _FE_DFL_ENV;
806 enum fenv_t* FE_DFL_ENV = &_FE_DFL_ENV;
808 else version (CRuntime_Microsoft)
810 private extern __gshared fenv_t _Fenv0;
812 enum FE_DFL_ENV = &_Fenv0;
814 else version (Darwin)
816 private extern __gshared fenv_t _FE_DFL_ENV;
818 enum FE_DFL_ENV = &_FE_DFL_ENV;
820 else version (FreeBSD)
822 private extern const fenv_t __fe_dfl_env;
824 enum FE_DFL_ENV = &__fe_dfl_env;
826 else version (NetBSD)
828 private extern const fenv_t __fe_dfl_env;
830 enum FE_DFL_ENV = &__fe_dfl_env;
832 else version (OpenBSD)
834 private extern const fenv_t __fe_dfl_env;
836 enum FE_DFL_ENV = &__fe_dfl_env;
838 else version (DragonFlyBSD)
840 private extern const fenv_t __fe_dfl_env;
842 enum FE_DFL_ENV = &__fe_dfl_env;
844 else version (CRuntime_Bionic)
846 private extern const fenv_t __fe_dfl_env;
848 enum FE_DFL_ENV = &__fe_dfl_env;
850 else version (Solaris)
852 private extern const fenv_t __fenv_def_env;
854 enum FE_DFL_ENV = &__fenv_def_env;
856 else version (CRuntime_Musl)
859 enum FE_DFL_ENV = cast(fenv_t*)(-1);
861 else version (CRuntime_UClibc)
864 enum FE_DFL_ENV = cast(fenv_t*)(-1);
868 static assert( false, "Unsupported platform" );
872 int feclearexcept(int excepts);
875 int fetestexcept(int excepts);
877 int feholdexcept(fenv_t* envp);
880 int fegetexceptflag(fexcept_t* flagp, int excepts);
882 int fesetexceptflag(const scope fexcept_t* flagp, int excepts);
887 int fesetround(int round);
890 int fegetenv(fenv_t* envp);
892 int fesetenv(const scope fenv_t* envp);
894 // MS define feraiseexcept() and feupdateenv() inline.
895 version (CRuntime_Microsoft) // supported since MSVCRT 12 (VS 2013) only
898 int feraiseexcept()(int excepts)
906 static __gshared immutable(Entry[5]) table =
907 [ // Raise exception by evaluating num / denom:
908 { FE_INVALID, 0.0, 0.0 },
909 { FE_DIVBYZERO, 1.0, 0.0 },
910 { FE_OVERFLOW, 1e+300, 1e-300 },
911 { FE_UNDERFLOW, 1e-300, 1e+300 },
912 { FE_INEXACT, 2.0, 3.0 }
915 if ((excepts &= FE_ALL_EXCEPT) == 0)
918 // Raise the exceptions not masked:
920 foreach (i; 0 .. table.length)
922 if ((excepts & table[i].exceptVal) != 0)
923 ans = table[i].num / table[i].denom;
930 int feupdateenv()(const scope fenv_t* envp)
932 int excepts = fetestexcept(FE_ALL_EXCEPT);
933 return (fesetenv(envp) != 0 || feraiseexcept(excepts) != 0 ? 1 : 0);
939 int feraiseexcept(int excepts);
941 int feupdateenv(const scope fenv_t* envp);