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
)
30 version (ARM
) version = ARM_Any
;
31 version (AArch64
) version = ARM_Any
;
32 version (HPPA
) version = HPPA_Any
;
33 version (MIPS32
) version = MIPS_Any
;
34 version (MIPS64
) version = MIPS_Any
;
35 version (PPC
) version = PPC_Any
;
36 version (PPC64
) version = PPC_Any
;
37 version (RISCV32
) version = RISCV_Any
;
38 version (RISCV64
) version = RISCV_Any
;
39 version (S390
) version = IBMZ_Any
;
40 version (SPARC
) version = SPARC_Any
;
41 version (SPARC64
) version = SPARC_Any
;
42 version (SystemZ
) version = IBMZ_Any
;
43 version (X86
) version = X86_Any
;
44 version (X86_64
) version = X86_Any
;
48 version (CRuntime_Glibc
)
53 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h
58 ushort __control_word
;
68 ushort __data_selector
;
72 alias fexcept_t
= ushort;
74 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h
79 ushort __control_word
;
89 ushort __data_selector
;
94 alias fexcept_t
= ushort;
96 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/hppa/bits/fenv.h
97 else version (HPPA_Any
)
105 alias fexcept_t
= uint;
107 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mips/bits/fenv.h
108 else version (MIPS_Any
)
112 uint __fp_control_register
;
115 alias fexcept_t
= ushort;
117 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/aarch64/bits/fenv.h
118 else version (AArch64
)
126 alias fexcept_t
= uint;
128 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/bits/fenv.h
136 alias fexcept_t
= uint;
138 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/bits/fenv.h
139 else version (PPC_Any
)
141 alias fenv_t
= double;
142 alias fexcept_t
= uint;
144 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/riscv/bits/fenv.h
145 else version (RISCV_Any
)
148 alias fexcept_t
= uint;
150 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/fpu/bits/fenv.h
151 else version (SPARC_Any
)
153 import core
.stdc
.config
: c_ulong
;
155 alias fenv_t
= c_ulong
;
156 alias fexcept_t
= c_ulong
;
158 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/s390/fpu/bits/fenv.h
159 else version (IBMZ_Any
)
167 alias fexcept_t
= uint;
169 else version (LoongArch64
)
173 uint __fp_control_register
;
176 alias fexcept_t
= uint;
180 static assert(0, "Unimplemented architecture");
183 else version (CRuntime_DigitalMars
)
192 alias fexcept_t
= int;
194 else version (CRuntime_Microsoft
)
202 alias fexcept_t
= uint;
204 else version (Darwin
)
209 alias uint fexcept_t
;
211 version (LittleEndian
)
221 alias ushort fexcept_t
;
224 else version (FreeBSD
)
236 alias ushort fexcept_t
;
238 else version (NetBSD
)
246 uint control
; /* Control word register */
247 uint status
; /* Status word register */
248 uint tag
; /* Tag word register */
249 uint[4] others
; /* EIP, Pointer Selector, etc */
253 uint mxcsr
; /* Control and status register */
262 ushort control
; /* Control word register */
264 ushort status
; /* Status word register */
266 ushort tag
; /* Tag word register */
268 uint[4] others
; /* EIP, Pointer Selector, etc */
271 uint mxcsr
; /* Control and status register */
276 alias uint fexcept_t
;
278 else version (OpenBSD
)
292 alias fexcept_t
= uint;
294 else version (DragonFlyBSD
)
310 alias uint fexcept_t
;
312 else version (CRuntime_Bionic
)
326 alias ushort fexcept_t
;
331 alias uint fexcept_t
;
333 else version (AArch64
)
341 alias uint fexcept_t
;
343 else version (X86_64
)
359 alias uint fexcept_t
;
363 static assert(false, "Architecture not supported.");
366 else version (Solaris
)
368 import core
.stdc
.config
: c_ulong
;
370 enum FEX_NUM_EXC
= 12;
375 void function() __handler
;
380 fex_handler_t
[FEX_NUM_EXC
] __handler
;
386 else version (CRuntime_Musl
)
395 alias uint fexcept_t
;
399 import core
.stdc
.config
: c_ulong
;
405 alias c_ulong fexcept_t
;
407 else version (IBMZ_Any
)
410 alias uint fexcept_t
;
412 else version (MIPS_Any
)
418 alias ushort fexcept_t
;
420 else version (PPC_Any
)
423 alias uint fexcept_t
;
425 else version (X86_Any
)
429 ushort __control_word
;
431 ushort __status_word
;
436 ushort __cs_selector
;
439 ushort __data_selector
;
444 alias ushort fexcept_t
;
448 static assert(false, "Architecture not supported.");
451 else version (CRuntime_UClibc
)
457 ushort __control_word
;
459 ushort __status_word
;
464 ushort __cs_selector
;
467 ushort __data_selector
;
471 alias fexcept_t
= ushort;
473 else version (X86_64
)
477 ushort __control_word
;
479 ushort __status_word
;
484 ushort __cs_selector
;
487 ushort __data_selector
;
492 alias fexcept_t
= ushort;
494 else version (MIPS_Any
)
498 uint __fp_control_register
;
501 alias fexcept_t
= ushort;
510 alias fexcept_t
= uint;
514 static assert(false, "Architecture not supported.");
519 static assert( false, "Unsupported platform" );
522 version (CRuntime_Microsoft
)
527 FE_UNDERFLOW
= 2, ///
529 FE_DIVBYZERO
= 8, ///
530 FE_INVALID
= 0x10, ///
531 FE_ALL_EXCEPT
= 0x1F, ///
532 FE_TONEAREST
= 0, ///
533 FE_UPWARD
= 0x100, ///
534 FE_DOWNWARD
= 0x200, ///
535 FE_TOWARDZERO
= 0x300, ///
538 else version (Solaris
)
557 FE_ALL_EXCEPT
= 0x1f,
561 else version (X86_Any
)
578 FE_ALL_EXCEPT
= 0x3d,
583 static assert(0, "Unimplemented architecture");
590 // Define bits representing the exception.
593 FE_INVALID
= 0x01, ///
594 FE_DENORMAL
= 0x02, /// non-standard
595 FE_DIVBYZERO
= 0x04, ///
596 FE_OVERFLOW
= 0x08, ///
597 FE_UNDERFLOW
= 0x10, ///
598 FE_INEXACT
= 0x20, ///
599 FE_ALL_EXCEPT
= 0x3F, ///
602 // The ix87 FPU supports all of the four defined rounding modes.
605 FE_TONEAREST
= 0, ///
606 FE_DOWNWARD
= 0x400, ///
607 FE_UPWARD
= 0x800, ///
608 FE_TOWARDZERO
= 0xC00, ///
611 else version (X86_64
)
613 // Define bits representing the exception.
616 FE_INVALID
= 0x01, ///
617 FE_DENORMAL
= 0x02, /// non-standard
618 FE_DIVBYZERO
= 0x04, ///
619 FE_OVERFLOW
= 0x08, ///
620 FE_UNDERFLOW
= 0x10, ///
621 FE_INEXACT
= 0x20, ///
622 FE_ALL_EXCEPT
= 0x3F, ///
625 // The ix87 FPU supports all of the four defined rounding modes.
628 FE_TONEAREST
= 0, ///
629 FE_DOWNWARD
= 0x400, ///
630 FE_UPWARD
= 0x800, ///
631 FE_TOWARDZERO
= 0xC00, ///
634 else version (ARM_Any
)
636 // Define bits representing exceptions in the FPU status word.
640 FE_DIVBYZERO
= 2, ///
642 FE_UNDERFLOW
= 8, ///
644 FE_ALL_EXCEPT
= 31, ///
647 // VFP supports all of the four defined rounding modes.
650 FE_TONEAREST
= 0, ///
651 FE_UPWARD
= 0x400000, ///
652 FE_DOWNWARD
= 0x800000, ///
653 FE_TOWARDZERO
= 0xC00000, ///
656 else version (HPPA_Any
)
658 // Define bits representing the exception.
661 FE_INEXACT
= 0x01, ///
662 FE_UNDERFLOW
= 0x02, ///
663 FE_OVERFLOW
= 0x04, ///
664 FE_DIVBYZERO
= 0x08, ///
665 FE_INVALID
= 0x10, ///
666 FE_ALL_EXCEPT
= 0x1F, ///
669 // The HPPA FPU supports all of the four defined rounding modes.
672 FE_TONEAREST
= 0x0, ///
673 FE_TOWARDZERO
= 0x200, ///
674 FE_UPWARD
= 0x400, ///
675 FE_DOWNWARD
= 0x600, ///
678 else version (MIPS_Any
)
680 // Define bits representing the exception.
683 FE_INEXACT
= 0x04, ///
684 FE_UNDERFLOW
= 0x08, ///
685 FE_OVERFLOW
= 0x10, ///
686 FE_DIVBYZERO
= 0x20, ///
687 FE_INVALID
= 0x40, ///
688 FE_ALL_EXCEPT
= 0x7C, ///
691 // The MIPS FPU supports all of the four defined rounding modes.
694 FE_TONEAREST
= 0x0, ///
695 FE_TOWARDZERO
= 0x1, ///
697 FE_DOWNWARD
= 0x3, ///
700 else version (PPC_Any
)
702 // Define bits representing the exception.
705 FE_INEXACT
= 0x2000000, ///
706 FE_DIVBYZERO
= 0x4000000, ///
707 FE_UNDERFLOW
= 0x8000000, ///
708 FE_OVERFLOW
= 0x10000000, ///
709 FE_INVALID
= 0x20000000, ///
710 FE_INVALID_SNAN
= 0x1000000, /// non-standard
711 FE_INVALID_ISI
= 0x800000, /// non-standard
712 FE_INVALID_IDI
= 0x400000, /// non-standard
713 FE_INVALID_ZDZ
= 0x200000, /// non-standard
714 FE_INVALID_IMZ
= 0x100000, /// non-standard
715 FE_INVALID_COMPARE
= 0x80000, /// non-standard
716 FE_INVALID_SOFTWARE
= 0x400, /// non-standard
717 FE_INVALID_SQRT
= 0x200, /// non-standard
718 FE_INVALID_INTEGER_CONVERSION
= 0x100, /// non-standard
719 FE_ALL_INVALID
= 0x1F80700, /// non-standard
720 FE_ALL_EXCEPT
= 0x3E000000, ///
723 // PowerPC chips support all of the four defined rounding modes.
726 FE_TONEAREST
= 0, ///
727 FE_TOWARDZERO
= 1, ///
732 else version (RISCV_Any
)
734 // Define bits representing exceptions in the FPSR status word.
737 FE_INEXACT
= 0x01, ///
738 FE_UNDERFLOW
= 0x02, ///
739 FE_OVERFLOW
= 0x04, ///
740 FE_DIVBYZERO
= 0x08, ///
741 FE_INVALID
= 0x10, ///
742 FE_ALL_EXCEPT
= 0x1f, ///
745 // Define bits representing rounding modes in the FPCR Rmode field.
748 FE_TONEAREST
= 0x0, ///
749 FE_TOWARDZERO
= 0x1, ///
750 FE_DOWNWARD
= 0x2, ///
754 else version (SPARC_Any
)
756 // Define bits representing the exception.
759 FE_INVALID
= 0x200, ///
760 FE_OVERFLOW
= 0x100, ///
761 FE_UNDERFLOW
= 0x80, ///
762 FE_DIVBYZERO
= 0x40, ///
763 FE_INEXACT
= 0x20, ///
764 FE_ALL_EXCEPT
= 0x3E0, ///
767 // The Sparc FPU supports all of the four defined rounding modes.
770 FE_TONEAREST
= 0x0, ///
771 FE_TOWARDZERO
= 0x40000000, ///
772 FE_UPWARD
= 0x80000000, ///
773 FE_DOWNWARD
= 0xc0000000, ///
776 else version (IBMZ_Any
)
778 // Define bits representing the exception.
781 FE_INVALID
= 0x80, ///
782 FE_DIVBYZERO
= 0x40, ///
783 FE_OVERFLOW
= 0x20, ///
784 FE_UNDERFLOW
= 0x10, ///
785 FE_INEXACT
= 0x08, ///
786 FE_ALL_EXCEPT
= 0xF8, ///
789 // SystemZ supports all of the four defined rounding modes.
792 FE_TONEAREST
= 0x0, ///
793 FE_DOWNWARD
= 0x3, ///
795 FE_TOWARDZERO
= 0x1, ///
798 else version (LoongArch64
)
800 // Define bits representing exceptions in the FPSR status word.
803 FE_INEXACT
= 0x010000, ///
804 FE_UNDERFLOW
= 0x020000, ///
805 FE_OVERFLOW
= 0x040000, ///
806 FE_DIVBYZERO
= 0x080000, ///
807 FE_INVALID
= 0x100000, ///
808 FE_ALL_EXCEPT
= 0x1f0000, ///
811 // Define bits representing rounding modes in the FPCR Rmode field.
814 FE_TONEAREST
= 0x000, ///
815 FE_TOWARDZERO
= 0x100, ///
816 FE_DOWNWARD
= 0x200, ///
817 FE_UPWARD
= 0x300, ///
822 static assert(0, "Unimplemented architecture");
830 enum FE_DFL_ENV
= cast(fenv_t
*)(-1);
832 else version (CRuntime_DigitalMars
)
834 private extern __gshared fenv_t _FE_DFL_ENV
;
836 enum fenv_t
* FE_DFL_ENV
= &_FE_DFL_ENV
;
838 else version (CRuntime_Microsoft
)
840 private extern __gshared fenv_t _Fenv0
;
842 enum FE_DFL_ENV
= &_Fenv0
;
844 else version (Darwin
)
846 private extern __gshared fenv_t _FE_DFL_ENV
;
848 enum FE_DFL_ENV
= &_FE_DFL_ENV
;
850 else version (FreeBSD
)
852 private extern const fenv_t __fe_dfl_env
;
854 enum FE_DFL_ENV
= &__fe_dfl_env
;
856 else version (NetBSD
)
858 private extern const fenv_t __fe_dfl_env
;
860 enum FE_DFL_ENV
= &__fe_dfl_env
;
862 else version (OpenBSD
)
864 private extern const fenv_t __fe_dfl_env
;
866 enum FE_DFL_ENV
= &__fe_dfl_env
;
868 else version (DragonFlyBSD
)
870 private extern const fenv_t __fe_dfl_env
;
872 enum FE_DFL_ENV
= &__fe_dfl_env
;
874 else version (CRuntime_Bionic
)
876 private extern const fenv_t __fe_dfl_env
;
878 enum FE_DFL_ENV
= &__fe_dfl_env
;
880 else version (Solaris
)
882 private extern const fenv_t __fenv_def_env
;
884 enum FE_DFL_ENV
= &__fenv_def_env
;
886 else version (CRuntime_Musl
)
889 enum FE_DFL_ENV
= cast(fenv_t
*)(-1);
891 else version (CRuntime_UClibc
)
894 enum FE_DFL_ENV
= cast(fenv_t
*)(-1);
898 static assert( false, "Unsupported platform" );
902 int feclearexcept(int excepts
);
905 int fetestexcept(int excepts
);
907 int feholdexcept(fenv_t
* envp
);
910 int fegetexceptflag(fexcept_t
* flagp
, int excepts
);
912 int fesetexceptflag(const scope fexcept_t
* flagp
, int excepts
);
917 int fesetround(int round
);
920 int fegetenv(fenv_t
* envp
);
922 int fesetenv(const scope fenv_t
* envp
);
924 // MS define feraiseexcept() and feupdateenv() inline.
925 version (CRuntime_Microsoft
) // supported since MSVCRT 12 (VS 2013) only
928 int feraiseexcept()(int excepts
)
936 static __gshared
immutable(Entry
[5]) table
=
937 [ // Raise exception by evaluating num / denom:
938 { FE_INVALID
, 0.0, 0.0 },
939 { FE_DIVBYZERO
, 1.0, 0.0 },
940 { FE_OVERFLOW
, 1e+300, 1e-300 },
941 { FE_UNDERFLOW
, 1e-300, 1e+300 },
942 { FE_INEXACT
, 2.0, 3.0 }
945 if ((excepts
&= FE_ALL_EXCEPT
) == 0)
948 // Raise the exceptions not masked:
950 foreach (i
; 0 .. table
.length
)
952 if ((excepts
& table
[i
].exceptVal
) != 0)
953 ans
= table
[i
].num
/ table
[i
].denom
;
960 int feupdateenv()(const scope fenv_t
* envp
)
962 int excepts
= fetestexcept(FE_ALL_EXCEPT
);
963 return (fesetenv(envp
) != 0 ||
feraiseexcept(excepts
) != 0 ?
1 : 0);
969 int feraiseexcept(int excepts
);
971 int feupdateenv(const scope fenv_t
* envp
);