xref: /netbsd-src/external/gpl3/gcc/dist/libphobos/libdruntime/core/stdc/fenv.d (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1 /**
2  * D header file for C99.
3  *
4  * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_fenv.h.html, _fenv.h)
5  *
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)
13  */
14 
15 module core.stdc.fenv;
16 
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;
25 
26 extern (C):
27 @system:
28 nothrow:
29 @nogc:
30 
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;
46 
47 version (MinGW)
48     version = GNUFP;
49 version (CRuntime_Glibc)
50     version = GNUFP;
51 
version(GNUFP)52 version (GNUFP)
53 {
54     // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h
55     version (X86)
56     {
57         struct fenv_t
58         {
59             ushort __control_word;
60             ushort __unused1;
61             ushort __status_word;
62             ushort __unused2;
63             ushort __tags;
64             ushort __unused3;
65             uint   __eip;
66             ushort __cs_selector;
67             ushort __opcode;
68             uint   __data_offset;
69             ushort __data_selector;
70             ushort __unused5;
71         }
72 
73         alias fexcept_t = ushort;
74     }
75     // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h
76     else version (X86_64)
77     {
78         struct fenv_t
79         {
80             ushort __control_word;
81             ushort __unused1;
82             ushort __status_word;
83             ushort __unused2;
84             ushort __tags;
85             ushort __unused3;
86             uint   __eip;
87             ushort __cs_selector;
88             ushort __opcode;
89             uint   __data_offset;
90             ushort __data_selector;
91             ushort __unused5;
92             uint   __mxcsr;
93         }
94 
95         alias fexcept_t = ushort;
96     }
97     // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/hppa/bits/fenv.h
98     else version (HPPA_Any)
99     {
100         struct fenv_t
101         {
102             uint    __status_word;
103             uint[7] __exception;
104         }
105 
106         alias fexcept_t = uint;
107     }
108     // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mips/bits/fenv.h
109     else version (MIPS_Any)
110     {
111         struct fenv_t
112         {
113             uint   __fp_control_register;
114         }
115 
116         alias fexcept_t = ushort;
117     }
118     // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/aarch64/bits/fenv.h
119     else version (AArch64)
120     {
121         struct fenv_t
122         {
123             uint __fpcr;
124             uint __fpsr;
125         }
126 
127         alias fexcept_t = uint;
128     }
129     // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/bits/fenv.h
130     else version (ARM)
131     {
132         struct fenv_t
133         {
134             uint __cw;
135         }
136 
137         alias fexcept_t = uint;
138     }
139     // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/bits/fenv.h
140     else version (PPC_Any)
141     {
142         alias fenv_t = double;
143         alias fexcept_t = uint;
144     }
145     // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/riscv/bits/fenv.h
146     else version (RISCV_Any)
147     {
148         alias fenv_t = uint;
149         alias fexcept_t = uint;
150     }
151     // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/fpu/bits/fenv.h
152     else version (SPARC_Any)
153     {
154         import core.stdc.config : c_ulong;
155 
156         alias fenv_t = c_ulong;
157         alias fexcept_t = c_ulong;
158     }
159     // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/s390/fpu/bits/fenv.h
160     else version (IBMZ_Any)
161     {
162         struct fenv_t
163         {
164             fexcept_t __fpc;
165             void*     __unused;
166         }
167 
168         alias fexcept_t = uint;
169     }
170     else
171     {
172         static assert(0, "Unimplemented architecture");
173     }
174 }
version(CRuntime_DigitalMars)175 else version (CRuntime_DigitalMars)
176 {
177     struct fenv_t
178     {
179         ushort    status;
180         ushort    control;
181         ushort    round;
182         ushort[2] reserved;
183     }
184     alias fexcept_t = int;
185 }
version(CRuntime_Microsoft)186 else version (CRuntime_Microsoft)
187 {
188     struct fenv_t
189     {
190         uint ctl;
191         uint stat;
192     }
193 
194     alias fexcept_t = uint;
195 }
version(Darwin)196 else version (Darwin)
197 {
198     version (BigEndian)
199     {
200         alias uint fenv_t;
201         alias uint fexcept_t;
202     }
203     version (LittleEndian)
204     {
205         struct fenv_t
206         {
207             ushort  __control;
208             ushort  __status;
209             uint    __mxcsr;
210             byte[8] __reserved;
211         }
212 
213         alias ushort fexcept_t;
214     }
215 }
version(FreeBSD)216 else version (FreeBSD)
217 {
218     struct fenv_t
219     {
220         ushort __control;
221         ushort __mxcsr_hi;
222         ushort __status;
223         ushort __mxcsr_lo;
224         uint __tag;
225         byte[16] __other;
226     }
227 
228     alias ushort fexcept_t;
229 }
version(NetBSD)230 else version (NetBSD)
231 {
232     version (X86_64)
233     {
234         struct fenv_t
235         {
236             struct _x87
237             {
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 */
242             }
243             _x87 x87;
244 
245             uint mxcsr;                 /* Control and status register */
246         }
247    }
248    version (X86)
249    {
250         struct fenv_t
251         {
252             struct _x87
253             {
254                     ushort control;     /* Control word register */
255                     ushort unused1;
256                     ushort status;      /* Status word register */
257                     ushort unused2;
258                     ushort tag;         /* Tag word register */
259                     ushort unused3;
260                     uint[4] others;     /* EIP, Pointer Selector, etc */
261             }
262             _x87 x87;
263             uint mxcsr;                 /* Control and status register */
264         }
265 
266     }
267 
268     alias uint fexcept_t;
269 }
270 else version (OpenBSD)
271 {
272     struct fenv_t
273     {
274         struct __x87
275         {
276             uint    __control;
277             uint    __status;
278             uint    __tag;
279             uint[4] __others;
280         }
281     }
282     uint __mxcsr;
283 
284     alias fexcept_t = uint;
285 }
286 else version (DragonFlyBSD)
287 {
288     struct fenv_t
289     {
290         struct _x87
291         {
292                 uint control;
293                 uint status;
294                 uint tag;
295                 uint[4] others;
296         }
297         _x87 x87;
298 
299         uint mxcsr;
300     }
301 
302     alias uint fexcept_t;
303 }
304 else version (CRuntime_Bionic)
305 {
306     version (X86)
307     {
308         struct fenv_t
309         {
310             ushort   __control;
311             ushort   __mxcsr_hi;
312             ushort   __status;
313             ushort   __mxcsr_lo;
314             uint     __tag;
315             byte[16] __other;
316         }
317 
318         alias ushort fexcept_t;
319     }
320     else version (ARM)
321     {
322         alias uint fenv_t;
323         alias uint fexcept_t;
324     }
325     else version (AArch64)
326     {
327         struct fenv_t
328         {
329             uint   __control;
330             uint   __status;
331         }
332 
333         alias uint fexcept_t;
334     }
335     else version (X86_64)
336     {
337         struct fenv_t
338         {
339             struct _x87
340             {
341                 uint    __control;
342                 uint    __status;
343                 uint    __tag;
344                 uint[4] __others;
345             }
346             _x87 __x87;
347 
348             uint __mxcsr;
349         }
350 
351         alias uint fexcept_t;
352     }
353     else
354     {
355         static assert(false, "Architecture not supported.");
356     }
357 }
358 else version (Solaris)
359 {
360     import core.stdc.config : c_ulong;
361 
362     enum FEX_NUM_EXC = 12;
363 
364     struct fex_handler_t
365     {
366         int             __mode;
367         void function() __handler;
368     }
369 
370     struct fenv_t
371     {
372         fex_handler_t[FEX_NUM_EXC]  __handler;
373         c_ulong                     __fsr;
374     }
375 
376     alias int fexcept_t;
377 }
378 else version (CRuntime_Musl)
379 {
380     version (AArch64)
381     {
382         struct fenv_t
383         {
384             uint __fpcr;
385             uint __fpsr;
386         }
387         alias uint fexcept_t;
388     }
389     else version (ARM)
390     {
391         import core.stdc.config : c_ulong;
392 
393         struct fenv_t
394         {
395             c_ulong __cw;
396         }
397         alias c_ulong fexcept_t;
398     }
399     else version (IBMZ_Any)
400     {
401         alias uint fenv_t;
402         alias uint fexcept_t;
403     }
404     else version (MIPS_Any)
405     {
406         struct fenv_t
407         {
408             uint __cw;
409         }
410         alias ushort fexcept_t;
411     }
412     else version (PPC_Any)
413     {
414         alias double fenv_t;
415         alias uint fexcept_t;
416     }
417     else version (X86_Any)
418     {
419         struct fenv_t
420         {
421             ushort __control_word;
422             ushort __unused1;
423             ushort __status_word;
424             ushort __unused2;
425             ushort __tags;
426             ushort __unused3;
427             uint   __eip;
428             ushort __cs_selector;
429             ushort __opcode;
430             uint   __data_offset;
431             ushort __data_selector;
432             ushort __unused5;
433             version (X86_64)
434                 uint __mxcsr;
435         }
436         alias ushort fexcept_t;
437     }
438     else
439     {
440         static assert(false, "Architecture not supported.");
441     }
442 }
443 else version (CRuntime_UClibc)
444 {
445     version (X86)
446     {
447         struct fenv_t
448         {
449             ushort __control_word;
450             ushort __unused1;
451             ushort __status_word;
452             ushort __unused2;
453             ushort __tags;
454             ushort __unused3;
455             uint   __eip;
456             ushort __cs_selector;
457             ushort __opcode;
458             uint   __data_offset;
459             ushort __data_selector;
460             ushort __unused5;
461         }
462 
463         alias fexcept_t = ushort;
464     }
465     else version (X86_64)
466     {
467         struct fenv_t
468         {
469             ushort __control_word;
470             ushort __unused1;
471             ushort __status_word;
472             ushort __unused2;
473             ushort __tags;
474             ushort __unused3;
475             uint   __eip;
476             ushort __cs_selector;
477             ushort __opcode;
478             uint   __data_offset;
479             ushort __data_selector;
480             ushort __unused5;
481             uint   __mxcsr;
482         }
483 
484         alias fexcept_t = ushort;
485     }
486     else version (MIPS_Any)
487     {
488         struct fenv_t
489         {
490             uint __fp_control_register;
491         }
492 
493         alias fexcept_t = ushort;
494     }
495     else version (ARM)
496     {
497         struct fenv_t
498         {
499             uint __cw;
500         }
501 
502         alias fexcept_t = uint;
503     }
504     else
505     {
506         static assert(false, "Architecture not supported.");
507     }
508 }
509 else
510 {
511     static assert( false, "Unsupported platform" );
512 }
513 
514 version (CRuntime_Microsoft)
515 {
516     enum
517     {
518         FE_INEXACT      = 1, ///
519         FE_UNDERFLOW    = 2, ///
520         FE_OVERFLOW     = 4, ///
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, ///
528     }
529 }
530 else version (Solaris)
531 {
532     version (SPARC_Any)
533     {
534         enum
535         {
536             FE_TONEAREST    = 0,
537             FE_TOWARDZERO   = 1,
538             FE_UPWARD       = 2,
539             FE_DOWNWARD     = 3,
540         }
541 
542         enum
543         {
544             FE_INEXACT      = 0x01,
545             FE_DIVBYZERO    = 0x02,
546             FE_UNDERFLOW    = 0x04,
547             FE_OVERFLOW     = 0x08,
548             FE_INVALID      = 0x10,
549             FE_ALL_EXCEPT   = 0x1f,
550         }
551 
552     }
553     else version (X86_Any)
554     {
555         enum
556         {
557             FE_TONEAREST    = 0,
558             FE_DOWNWARD     = 1,
559             FE_UPWARD       = 2,
560             FE_TOWARDZERO   = 3,
561         }
562 
563         enum
564         {
565             FE_INVALID      = 0x01,
566             FE_DIVBYZERO    = 0x04,
567             FE_OVERFLOW     = 0x08,
568             FE_UNDERFLOW    = 0x10,
569             FE_INEXACT      = 0x20,
570             FE_ALL_EXCEPT   = 0x3d,
571         }
572     }
573     else
574     {
575         static assert(0, "Unimplemented architecture");
576     }
577 }
578 else
579 {
580     version (X86)
581     {
582         // Define bits representing the exception.
583         enum
584         {
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, ///
592         }
593 
594         // The ix87 FPU supports all of the four defined rounding modes.
595         enum
596         {
597             FE_TONEAREST    = 0, ///
598             FE_DOWNWARD     = 0x400, ///
599             FE_UPWARD       = 0x800, ///
600             FE_TOWARDZERO   = 0xC00, ///
601         }
602     }
603     else version (X86_64)
604     {
605         // Define bits representing the exception.
606         enum
607         {
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, ///
615         }
616 
617         // The ix87 FPU supports all of the four defined rounding modes.
618         enum
619         {
620             FE_TONEAREST    = 0, ///
621             FE_DOWNWARD     = 0x400, ///
622             FE_UPWARD       = 0x800, ///
623             FE_TOWARDZERO   = 0xC00, ///
624         }
625     }
626     else version (ARM_Any)
627     {
628         // Define bits representing exceptions in the FPU status word.
629         enum
630         {
631             FE_INVALID      = 1,  ///
632             FE_DIVBYZERO    = 2,  ///
633             FE_OVERFLOW     = 4,  ///
634             FE_UNDERFLOW    = 8,  ///
635             FE_INEXACT      = 16, ///
636             FE_ALL_EXCEPT   = 31, ///
637         }
638 
639         // VFP supports all of the four defined rounding modes.
640         enum
641         {
642             FE_TONEAREST    = 0,        ///
643             FE_UPWARD       = 0x400000, ///
644             FE_DOWNWARD     = 0x800000, ///
645             FE_TOWARDZERO   = 0xC00000, ///
646         }
647     }
648     else version (HPPA_Any)
649     {
650         // Define bits representing the exception.
651         enum
652         {
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, ///
659         }
660 
661         // The HPPA FPU supports all of the four defined rounding modes.
662         enum
663         {
664             FE_TONEAREST    =   0x0, ///
665             FE_TOWARDZERO   = 0x200, ///
666             FE_UPWARD       = 0x400, ///
667             FE_DOWNWARD     = 0x600, ///
668         }
669     }
670     else version (MIPS_Any)
671     {
672         // Define bits representing the exception.
673         enum
674         {
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, ///
681         }
682 
683         // The MIPS FPU supports all of the four defined rounding modes.
684         enum
685         {
686             FE_TONEAREST    = 0x0, ///
687             FE_TOWARDZERO   = 0x1, ///
688             FE_UPWARD       = 0x2, ///
689             FE_DOWNWARD     = 0x3, ///
690         }
691     }
692     else version (PPC_Any)
693     {
694         // Define bits representing the exception.
695         enum
696         {
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, ///
713         }
714 
715         // PowerPC chips support all of the four defined rounding modes.
716         enum
717         {
718             FE_TONEAREST    = 0, ///
719             FE_TOWARDZERO   = 1, ///
720             FE_UPWARD       = 2, ///
721             FE_DOWNWARD     = 3, ///
722         }
723     }
724     else version (RISCV_Any)
725     {
726         // Define bits representing exceptions in the FPSR status word.
727         enum
728         {
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, ///
735         }
736 
737         // Define bits representing rounding modes in the FPCR Rmode field.
738         enum
739         {
740             FE_TONEAREST    = 0x0, ///
741             FE_TOWARDZERO   = 0x1, ///
742             FE_DOWNWARD     = 0x2, ///
743             FE_UPWARD       = 0x3, ///
744         }
745     }
746     else version (SPARC_Any)
747     {
748         // Define bits representing the exception.
749         enum
750         {
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, ///
757         }
758 
759         // The Sparc FPU supports all of the four defined rounding modes.
760         enum
761         {
762             FE_TONEAREST    = 0x0,        ///
763             FE_TOWARDZERO   = 0x40000000, ///
764             FE_UPWARD       = 0x80000000, ///
765             FE_DOWNWARD     = 0xc0000000, ///
766         }
767     }
768     else version (IBMZ_Any)
769     {
770         // Define bits representing the exception.
771         enum
772         {
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, ///
779         }
780 
781         // SystemZ supports all of the four defined rounding modes.
782         enum
783         {
784             FE_TONEAREST    = 0x0, ///
785             FE_DOWNWARD     = 0x3, ///
786             FE_UPWARD       = 0x2, ///
787             FE_TOWARDZERO   = 0x1, ///
788         }
789     }
790     else
791     {
792         static assert(0, "Unimplemented architecture");
793     }
794 
795 }
796 
797 version (GNUFP)
798 {
799     ///
800     enum FE_DFL_ENV = cast(fenv_t*)(-1);
801 }
802 else version (CRuntime_DigitalMars)
803 {
804     private extern __gshared fenv_t _FE_DFL_ENV;
805     ///
806     enum fenv_t* FE_DFL_ENV = &_FE_DFL_ENV;
807 }
808 else version (CRuntime_Microsoft)
809 {
810     private extern __gshared fenv_t _Fenv0;
811     ///
812     enum FE_DFL_ENV = &_Fenv0;
813 }
814 else version (Darwin)
815 {
816     private extern __gshared fenv_t _FE_DFL_ENV;
817     ///
818     enum FE_DFL_ENV = &_FE_DFL_ENV;
819 }
820 else version (FreeBSD)
821 {
822     private extern const fenv_t __fe_dfl_env;
823     ///
824     enum FE_DFL_ENV = &__fe_dfl_env;
825 }
826 else version (NetBSD)
827 {
828     private extern const fenv_t __fe_dfl_env;
829     ///
830     enum FE_DFL_ENV = &__fe_dfl_env;
831 }
832 else version (OpenBSD)
833 {
834     private extern const fenv_t __fe_dfl_env;
835     ///
836     enum FE_DFL_ENV = &__fe_dfl_env;
837 }
838 else version (DragonFlyBSD)
839 {
840     private extern const fenv_t __fe_dfl_env;
841     ///
842     enum FE_DFL_ENV = &__fe_dfl_env;
843 }
844 else version (CRuntime_Bionic)
845 {
846     private extern const fenv_t __fe_dfl_env;
847     ///
848     enum FE_DFL_ENV = &__fe_dfl_env;
849 }
850 else version (Solaris)
851 {
852     private extern const fenv_t __fenv_def_env;
853     ///
854     enum FE_DFL_ENV = &__fenv_def_env;
855 }
856 else version (CRuntime_Musl)
857 {
858     ///
859     enum FE_DFL_ENV = cast(fenv_t*)(-1);
860 }
861 else version (CRuntime_UClibc)
862 {
863     ///
864     enum FE_DFL_ENV = cast(fenv_t*)(-1);
865 }
866 else
867 {
868     static assert( false, "Unsupported platform" );
869 }
870 
871 ///
872 int feclearexcept(int excepts);
873 
874 ///
875 int fetestexcept(int excepts);
876 ///
877 int feholdexcept(fenv_t* envp);
878 
879 ///
880 int fegetexceptflag(fexcept_t* flagp, int excepts);
881 ///
882 int fesetexceptflag(const scope fexcept_t* flagp, int excepts);
883 
884 ///
885 int fegetround();
886 ///
887 int fesetround(int round);
888 
889 ///
890 int fegetenv(fenv_t* envp);
891 ///
892 int fesetenv(const scope fenv_t* envp);
893 
894 // MS define feraiseexcept() and feupdateenv() inline.
895 version (CRuntime_Microsoft) // supported since MSVCRT 12 (VS 2013) only
896 {
897     ///
898     int feraiseexcept()(int excepts)
899     {
900         struct Entry
901         {
902             int    exceptVal;
903             double num;
904             double denom;
905         }
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    }
913         ];
914 
915         if ((excepts &= FE_ALL_EXCEPT) == 0)
916             return 0;
917 
918         // Raise the exceptions not masked:
919         double ans = void;
920         foreach (i; 0 .. table.length)
921         {
922             if ((excepts & table[i].exceptVal) != 0)
923                 ans = table[i].num / table[i].denom;
924         }
925 
926         return 0;
927     }
928 
929     ///
930     int feupdateenv()(const scope fenv_t* envp)
931     {
932         int excepts = fetestexcept(FE_ALL_EXCEPT);
933         return (fesetenv(envp) != 0 || feraiseexcept(excepts) != 0 ? 1 : 0);
934     }
935 }
936 else
937 {
938     ///
939     int feraiseexcept(int excepts);
940     ///
941     int feupdateenv(const scope fenv_t* envp);
942 }
943