d: Merge upstream dmd, druntime 4c18eed967, phobos d945686a4.
[official-gcc.git] / libphobos / libdruntime / core / stdc / fenv.d
blob288f9c25dc69d262ec4089c268ac4a8c81a2647e
1 /**
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)
10 * Authors: Sean Kelly
11 * Source: $(DRUNTIMESRC core/stdc/_fenv.d)
12 * Standards: ISO/IEC 9899:1999 (E)
15 module core.stdc.fenv;
17 version (OSX)
18 version = Darwin;
19 else version (iOS)
20 version = Darwin;
21 else version (TVOS)
22 version = Darwin;
23 else version (WatchOS)
24 version = Darwin;
26 extern (C):
27 nothrow:
28 @nogc:
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;
46 version (MinGW)
47 version = GNUFP;
48 version (CRuntime_Glibc)
49 version = GNUFP;
51 version (GNUFP)
53 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h
54 version (X86)
56 struct fenv_t
58 ushort __control_word;
59 ushort __unused1;
60 ushort __status_word;
61 ushort __unused2;
62 ushort __tags;
63 ushort __unused3;
64 uint __eip;
65 ushort __cs_selector;
66 ushort __opcode;
67 uint __data_offset;
68 ushort __data_selector;
69 ushort __unused5;
72 alias fexcept_t = ushort;
74 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h
75 else version (X86_64)
77 struct fenv_t
79 ushort __control_word;
80 ushort __unused1;
81 ushort __status_word;
82 ushort __unused2;
83 ushort __tags;
84 ushort __unused3;
85 uint __eip;
86 ushort __cs_selector;
87 ushort __opcode;
88 uint __data_offset;
89 ushort __data_selector;
90 ushort __unused5;
91 uint __mxcsr;
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)
99 struct fenv_t
101 uint __status_word;
102 uint[7] __exception;
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)
110 struct fenv_t
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)
120 struct fenv_t
122 uint __fpcr;
123 uint __fpsr;
126 alias fexcept_t = uint;
128 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/bits/fenv.h
129 else version (ARM)
131 struct fenv_t
133 uint __cw;
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)
147 alias fenv_t = uint;
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)
161 struct fenv_t
163 fexcept_t __fpc;
164 void* __unused;
167 alias fexcept_t = uint;
169 else version (LoongArch64)
171 struct fenv_t
173 uint __fp_control_register;
176 alias fexcept_t = uint;
178 else
180 static assert(0, "Unimplemented architecture");
183 else version (CRuntime_DigitalMars)
185 struct fenv_t
187 ushort status;
188 ushort control;
189 ushort round;
190 ushort[2] reserved;
192 alias fexcept_t = int;
194 else version (CRuntime_Microsoft)
196 struct fenv_t
198 uint ctl;
199 uint stat;
202 alias fexcept_t = uint;
204 else version (Darwin)
206 version (BigEndian)
208 alias uint fenv_t;
209 alias uint fexcept_t;
211 version (LittleEndian)
213 struct fenv_t
215 ushort __control;
216 ushort __status;
217 uint __mxcsr;
218 byte[8] __reserved;
221 alias ushort fexcept_t;
224 else version (FreeBSD)
226 struct fenv_t
228 ushort __control;
229 ushort __mxcsr_hi;
230 ushort __status;
231 ushort __mxcsr_lo;
232 uint __tag;
233 byte[16] __other;
236 alias ushort fexcept_t;
238 else version (NetBSD)
240 version (X86_64)
242 struct fenv_t
244 struct _x87
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 */
251 _x87 x87;
253 uint mxcsr; /* Control and status register */
256 version (X86)
258 struct fenv_t
260 struct _x87
262 ushort control; /* Control word register */
263 ushort unused1;
264 ushort status; /* Status word register */
265 ushort unused2;
266 ushort tag; /* Tag word register */
267 ushort unused3;
268 uint[4] others; /* EIP, Pointer Selector, etc */
270 _x87 x87;
271 uint mxcsr; /* Control and status register */
276 alias uint fexcept_t;
278 else version (OpenBSD)
280 struct fenv_t
282 struct __x87
284 uint __control;
285 uint __status;
286 uint __tag;
287 uint[4] __others;
290 uint __mxcsr;
292 alias fexcept_t = uint;
294 else version (DragonFlyBSD)
296 struct fenv_t
298 struct _x87
300 uint control;
301 uint status;
302 uint tag;
303 uint[4] others;
305 _x87 x87;
307 uint mxcsr;
310 alias uint fexcept_t;
312 else version (CRuntime_Bionic)
314 version (X86)
316 struct fenv_t
318 ushort __control;
319 ushort __mxcsr_hi;
320 ushort __status;
321 ushort __mxcsr_lo;
322 uint __tag;
323 byte[16] __other;
326 alias ushort fexcept_t;
328 else version (ARM)
330 alias uint fenv_t;
331 alias uint fexcept_t;
333 else version (AArch64)
335 struct fenv_t
337 uint __control;
338 uint __status;
341 alias uint fexcept_t;
343 else version (X86_64)
345 struct fenv_t
347 struct _x87
349 uint __control;
350 uint __status;
351 uint __tag;
352 uint[4] __others;
354 _x87 __x87;
356 uint __mxcsr;
359 alias uint fexcept_t;
361 else
363 static assert(false, "Architecture not supported.");
366 else version (Solaris)
368 import core.stdc.config : c_ulong;
370 enum FEX_NUM_EXC = 12;
372 struct fex_handler_t
374 int __mode;
375 void function() __handler;
378 struct fenv_t
380 fex_handler_t[FEX_NUM_EXC] __handler;
381 c_ulong __fsr;
384 alias int fexcept_t;
386 else version (CRuntime_Musl)
388 version (AArch64)
390 struct fenv_t
392 uint __fpcr;
393 uint __fpsr;
395 alias uint fexcept_t;
397 else version (ARM)
399 import core.stdc.config : c_ulong;
401 struct fenv_t
403 c_ulong __cw;
405 alias c_ulong fexcept_t;
407 else version (IBMZ_Any)
409 alias uint fenv_t;
410 alias uint fexcept_t;
412 else version (MIPS_Any)
414 struct fenv_t
416 uint __cw;
418 alias ushort fexcept_t;
420 else version (PPC_Any)
422 alias double fenv_t;
423 alias uint fexcept_t;
425 else version (X86_Any)
427 struct fenv_t
429 ushort __control_word;
430 ushort __unused1;
431 ushort __status_word;
432 ushort __unused2;
433 ushort __tags;
434 ushort __unused3;
435 uint __eip;
436 ushort __cs_selector;
437 ushort __opcode;
438 uint __data_offset;
439 ushort __data_selector;
440 ushort __unused5;
441 version (X86_64)
442 uint __mxcsr;
444 alias ushort fexcept_t;
446 else
448 static assert(false, "Architecture not supported.");
451 else version (CRuntime_UClibc)
453 version (X86)
455 struct fenv_t
457 ushort __control_word;
458 ushort __unused1;
459 ushort __status_word;
460 ushort __unused2;
461 ushort __tags;
462 ushort __unused3;
463 uint __eip;
464 ushort __cs_selector;
465 ushort __opcode;
466 uint __data_offset;
467 ushort __data_selector;
468 ushort __unused5;
471 alias fexcept_t = ushort;
473 else version (X86_64)
475 struct fenv_t
477 ushort __control_word;
478 ushort __unused1;
479 ushort __status_word;
480 ushort __unused2;
481 ushort __tags;
482 ushort __unused3;
483 uint __eip;
484 ushort __cs_selector;
485 ushort __opcode;
486 uint __data_offset;
487 ushort __data_selector;
488 ushort __unused5;
489 uint __mxcsr;
492 alias fexcept_t = ushort;
494 else version (MIPS_Any)
496 struct fenv_t
498 uint __fp_control_register;
501 alias fexcept_t = ushort;
503 else version (ARM)
505 struct fenv_t
507 uint __cw;
510 alias fexcept_t = uint;
512 else
514 static assert(false, "Architecture not supported.");
517 else
519 static assert( false, "Unsupported platform" );
522 version (CRuntime_Microsoft)
524 enum
526 FE_INEXACT = 1, ///
527 FE_UNDERFLOW = 2, ///
528 FE_OVERFLOW = 4, ///
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)
540 version (SPARC_Any)
542 enum
544 FE_TONEAREST = 0,
545 FE_TOWARDZERO = 1,
546 FE_UPWARD = 2,
547 FE_DOWNWARD = 3,
550 enum
552 FE_INEXACT = 0x01,
553 FE_DIVBYZERO = 0x02,
554 FE_UNDERFLOW = 0x04,
555 FE_OVERFLOW = 0x08,
556 FE_INVALID = 0x10,
557 FE_ALL_EXCEPT = 0x1f,
561 else version (X86_Any)
563 enum
565 FE_TONEAREST = 0,
566 FE_DOWNWARD = 1,
567 FE_UPWARD = 2,
568 FE_TOWARDZERO = 3,
571 enum
573 FE_INVALID = 0x01,
574 FE_DIVBYZERO = 0x04,
575 FE_OVERFLOW = 0x08,
576 FE_UNDERFLOW = 0x10,
577 FE_INEXACT = 0x20,
578 FE_ALL_EXCEPT = 0x3d,
581 else
583 static assert(0, "Unimplemented architecture");
586 else
588 version (X86)
590 // Define bits representing the exception.
591 enum
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.
603 enum
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.
614 enum
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.
626 enum
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.
637 enum
639 FE_INVALID = 1, ///
640 FE_DIVBYZERO = 2, ///
641 FE_OVERFLOW = 4, ///
642 FE_UNDERFLOW = 8, ///
643 FE_INEXACT = 16, ///
644 FE_ALL_EXCEPT = 31, ///
647 // VFP supports all of the four defined rounding modes.
648 enum
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.
659 enum
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.
670 enum
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.
681 enum
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.
692 enum
694 FE_TONEAREST = 0x0, ///
695 FE_TOWARDZERO = 0x1, ///
696 FE_UPWARD = 0x2, ///
697 FE_DOWNWARD = 0x3, ///
700 else version (PPC_Any)
702 // Define bits representing the exception.
703 enum
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.
724 enum
726 FE_TONEAREST = 0, ///
727 FE_TOWARDZERO = 1, ///
728 FE_UPWARD = 2, ///
729 FE_DOWNWARD = 3, ///
732 else version (RISCV_Any)
734 // Define bits representing exceptions in the FPSR status word.
735 enum
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.
746 enum
748 FE_TONEAREST = 0x0, ///
749 FE_TOWARDZERO = 0x1, ///
750 FE_DOWNWARD = 0x2, ///
751 FE_UPWARD = 0x3, ///
754 else version (SPARC_Any)
756 // Define bits representing the exception.
757 enum
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.
768 enum
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.
779 enum
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.
790 enum
792 FE_TONEAREST = 0x0, ///
793 FE_DOWNWARD = 0x3, ///
794 FE_UPWARD = 0x2, ///
795 FE_TOWARDZERO = 0x1, ///
798 else version (LoongArch64)
800 // Define bits representing exceptions in the FPSR status word.
801 enum
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.
812 enum
814 FE_TONEAREST = 0x000, ///
815 FE_TOWARDZERO = 0x100, ///
816 FE_DOWNWARD = 0x200, ///
817 FE_UPWARD = 0x300, ///
820 else
822 static assert(0, "Unimplemented architecture");
827 version (GNUFP)
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);
896 else
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);
915 int fegetround();
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)
930 struct Entry
932 int exceptVal;
933 double num;
934 double denom;
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)
946 return 0;
948 // Raise the exceptions not masked:
949 double ans = void;
950 foreach (i; 0 .. table.length)
952 if ((excepts & table[i].exceptVal) != 0)
953 ans = table[i].num / table[i].denom;
956 return 0;
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);
966 else
969 int feraiseexcept(int excepts);
971 int feupdateenv(const scope fenv_t* envp);