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 nothrow: 28 @nogc: 29 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; 45 46 version (MinGW) 47 version = GNUFP; 48 version (CRuntime_Glibc) 49 version = GNUFP; 50 51 version (GNUFP) 52 { 53 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h 54 version (X86) 55 { 56 struct fenv_t 57 { 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; 70 } 71 72 alias fexcept_t = ushort; 73 } 74 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h 75 else version (X86_64) 76 { 77 struct fenv_t 78 { 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; 92 } 93 94 alias fexcept_t = ushort; 95 } 96 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/hppa/bits/fenv.h 97 else version (HPPA_Any) 98 { 99 struct fenv_t 100 { 101 uint __status_word; 102 uint[7] __exception; 103 } 104 105 alias fexcept_t = uint; 106 } 107 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mips/bits/fenv.h 108 else version (MIPS_Any) 109 { 110 struct fenv_t 111 { 112 uint __fp_control_register; 113 } 114 115 alias fexcept_t = ushort; 116 } 117 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/aarch64/bits/fenv.h 118 else version (AArch64) 119 { 120 struct fenv_t 121 { 122 uint __fpcr; 123 uint __fpsr; 124 } 125 126 alias fexcept_t = uint; 127 } 128 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/bits/fenv.h 129 else version (ARM) 130 { 131 struct fenv_t 132 { 133 uint __cw; 134 } 135 136 alias fexcept_t = uint; 137 } 138 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/bits/fenv.h 139 else version (PPC_Any) 140 { 141 alias fenv_t = double; 142 alias fexcept_t = uint; 143 } 144 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/riscv/bits/fenv.h 145 else version (RISCV_Any) 146 { 147 alias fenv_t = uint; 148 alias fexcept_t = uint; 149 } 150 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/fpu/bits/fenv.h 151 else version (SPARC_Any) 152 { 153 import core.stdc.config : c_ulong; 154 155 alias fenv_t = c_ulong; 156 alias fexcept_t = c_ulong; 157 } 158 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/s390/fpu/bits/fenv.h 159 else version (IBMZ_Any) 160 { 161 struct fenv_t 162 { 163 fexcept_t __fpc; 164 void* __unused; 165 } 166 167 alias fexcept_t = uint; 168 } 169 else version (LoongArch64) 170 { 171 struct fenv_t 172 { 173 uint __fp_control_register; 174 } 175 176 alias fexcept_t = uint; 177 } 178 else 179 { 180 static assert(0, "Unimplemented architecture"); 181 } 182 } 183 else version (CRuntime_DigitalMars) 184 { 185 struct fenv_t 186 { 187 ushort status; 188 ushort control; 189 ushort round; 190 ushort[2] reserved; 191 } 192 alias fexcept_t = int; 193 } 194 else version (CRuntime_Microsoft) 195 { 196 struct fenv_t 197 { 198 uint ctl; 199 uint stat; 200 } 201 202 alias fexcept_t = uint; 203 } 204 else version (Darwin) 205 { 206 version (BigEndian) 207 { 208 alias uint fenv_t; 209 alias uint fexcept_t; 210 } 211 version (LittleEndian) 212 { 213 struct fenv_t 214 { 215 ushort __control; 216 ushort __status; 217 uint __mxcsr; 218 byte[8] __reserved; 219 } 220 221 alias ushort fexcept_t; 222 } 223 } 224 else version (FreeBSD) 225 { 226 struct fenv_t 227 { 228 ushort __control; 229 ushort __mxcsr_hi; 230 ushort __status; 231 ushort __mxcsr_lo; 232 uint __tag; 233 byte[16] __other; 234 } 235 236 alias ushort fexcept_t; 237 } 238 else version (NetBSD) 239 { 240 version (X86_64) 241 { 242 struct fenv_t 243 { 244 struct _x87 245 { 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 */ 250 } 251 _x87 x87; 252 253 uint mxcsr; /* Control and status register */ 254 } 255 } 256 version (X86) 257 { 258 struct fenv_t 259 { 260 struct _x87 261 { 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 */ 269 } 270 _x87 x87; 271 uint mxcsr; /* Control and status register */ 272 } 273 274 } 275 276 alias uint fexcept_t; 277 } 278 else version (OpenBSD) 279 { 280 struct fenv_t 281 { 282 struct __x87 283 { 284 uint __control; 285 uint __status; 286 uint __tag; 287 uint[4] __others; 288 } 289 } 290 uint __mxcsr; 291 292 alias fexcept_t = uint; 293 } 294 else version (DragonFlyBSD) 295 { 296 struct fenv_t 297 { 298 struct _x87 299 { 300 uint control; 301 uint status; 302 uint tag; 303 uint[4] others; 304 } 305 _x87 x87; 306 307 uint mxcsr; 308 } 309 310 alias uint fexcept_t; 311 } 312 else version (CRuntime_Bionic) 313 { 314 version (X86) 315 { 316 struct fenv_t 317 { 318 ushort __control; 319 ushort __mxcsr_hi; 320 ushort __status; 321 ushort __mxcsr_lo; 322 uint __tag; 323 byte[16] __other; 324 } 325 326 alias ushort fexcept_t; 327 } 328 else version (ARM) 329 { 330 alias uint fenv_t; 331 alias uint fexcept_t; 332 } 333 else version (AArch64) 334 { 335 struct fenv_t 336 { 337 uint __control; 338 uint __status; 339 } 340 341 alias uint fexcept_t; 342 } 343 else version (X86_64) 344 { 345 struct fenv_t 346 { 347 struct _x87 348 { 349 uint __control; 350 uint __status; 351 uint __tag; 352 uint[4] __others; 353 } 354 _x87 __x87; 355 356 uint __mxcsr; 357 } 358 359 alias uint fexcept_t; 360 } 361 else 362 { 363 static assert(false, "Architecture not supported."); 364 } 365 } 366 else version (Solaris) 367 { 368 import core.stdc.config : c_ulong; 369 370 enum FEX_NUM_EXC = 12; 371 372 struct fex_handler_t 373 { 374 int __mode; 375 void function() __handler; 376 } 377 378 struct fenv_t 379 { 380 fex_handler_t[FEX_NUM_EXC] __handler; 381 c_ulong __fsr; 382 } 383 384 alias int fexcept_t; 385 } 386 else version (CRuntime_Musl) 387 { 388 version (AArch64) 389 { 390 struct fenv_t 391 { 392 uint __fpcr; 393 uint __fpsr; 394 } 395 alias uint fexcept_t; 396 } 397 else version (ARM) 398 { 399 import core.stdc.config : c_ulong; 400 401 struct fenv_t 402 { 403 c_ulong __cw; 404 } 405 alias c_ulong fexcept_t; 406 } 407 else version (IBMZ_Any) 408 { 409 alias uint fenv_t; 410 alias uint fexcept_t; 411 } 412 else version (MIPS_Any) 413 { 414 struct fenv_t 415 { 416 uint __cw; 417 } 418 alias ushort fexcept_t; 419 } 420 else version (PPC_Any) 421 { 422 alias double fenv_t; 423 alias uint fexcept_t; 424 } 425 else version (X86_Any) 426 { 427 struct fenv_t 428 { 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; 443 } 444 alias ushort fexcept_t; 445 } 446 else version (WebAssembly) 447 { 448 // FIXME: verify 449 struct fenv_t 450 { 451 ushort __control_word; 452 ushort __unused1; 453 ushort __status_word; 454 ushort __unused2; 455 ushort __tags; 456 ushort __unused3; 457 uint __eip; 458 ushort __cs_selector; 459 ushort __opcode; 460 uint __data_offset; 461 ushort __data_selector; 462 ushort __unused5; 463 version (X86_64) 464 uint __mxcsr; 465 } 466 alias ushort fexcept_t; 467 } 468 else version (RICV64) 469 { 470 alias uint fenv_t; 471 alias uint fexcept_t; 472 } 473 else 474 { 475 static assert(false, "Architecture not supported."); 476 } 477 } 478 else version (CRuntime_UClibc) 479 { 480 version (X86) 481 { 482 struct fenv_t 483 { 484 ushort __control_word; 485 ushort __unused1; 486 ushort __status_word; 487 ushort __unused2; 488 ushort __tags; 489 ushort __unused3; 490 uint __eip; 491 ushort __cs_selector; 492 ushort __opcode; 493 uint __data_offset; 494 ushort __data_selector; 495 ushort __unused5; 496 } 497 498 alias fexcept_t = ushort; 499 } 500 else version (X86_64) 501 { 502 struct fenv_t 503 { 504 ushort __control_word; 505 ushort __unused1; 506 ushort __status_word; 507 ushort __unused2; 508 ushort __tags; 509 ushort __unused3; 510 uint __eip; 511 ushort __cs_selector; 512 ushort __opcode; 513 uint __data_offset; 514 ushort __data_selector; 515 ushort __unused5; 516 uint __mxcsr; 517 } 518 519 alias fexcept_t = ushort; 520 } 521 else version (MIPS_Any) 522 { 523 struct fenv_t 524 { 525 uint __fp_control_register; 526 } 527 528 alias fexcept_t = ushort; 529 } 530 else version (ARM) 531 { 532 struct fenv_t 533 { 534 uint __cw; 535 } 536 537 alias fexcept_t = uint; 538 } 539 else 540 { 541 static assert(false, "Architecture not supported."); 542 } 543 } 544 else version (FreeStanding) 545 { 546 struct fenv_t {} 547 alias fexcept_t = uint; 548 } 549 else 550 { 551 static assert( false, "Unsupported platform" ); 552 } 553 554 version (CRuntime_Microsoft) 555 { 556 enum 557 { 558 FE_INEXACT = 1, /// 559 FE_UNDERFLOW = 2, /// 560 FE_OVERFLOW = 4, /// 561 FE_DIVBYZERO = 8, /// 562 FE_INVALID = 0x10, /// 563 FE_ALL_EXCEPT = 0x1F, /// 564 FE_TONEAREST = 0, /// 565 FE_UPWARD = 0x100, /// 566 FE_DOWNWARD = 0x200, /// 567 FE_TOWARDZERO = 0x300, /// 568 } 569 } 570 else version (Solaris) 571 { 572 version (SPARC_Any) 573 { 574 enum 575 { 576 FE_TONEAREST = 0, 577 FE_TOWARDZERO = 1, 578 FE_UPWARD = 2, 579 FE_DOWNWARD = 3, 580 } 581 582 enum 583 { 584 FE_INEXACT = 0x01, 585 FE_DIVBYZERO = 0x02, 586 FE_UNDERFLOW = 0x04, 587 FE_OVERFLOW = 0x08, 588 FE_INVALID = 0x10, 589 FE_ALL_EXCEPT = 0x1f, 590 } 591 592 } 593 else version (X86_Any) 594 { 595 enum 596 { 597 FE_TONEAREST = 0, 598 FE_DOWNWARD = 1, 599 FE_UPWARD = 2, 600 FE_TOWARDZERO = 3, 601 } 602 603 enum 604 { 605 FE_INVALID = 0x01, 606 FE_DIVBYZERO = 0x04, 607 FE_OVERFLOW = 0x08, 608 FE_UNDERFLOW = 0x10, 609 FE_INEXACT = 0x20, 610 FE_ALL_EXCEPT = 0x3d, 611 } 612 } 613 else 614 { 615 static assert(0, "Unimplemented architecture"); 616 } 617 } 618 else 619 { 620 version (X86) 621 { 622 // Define bits representing the exception. 623 enum 624 { 625 FE_INVALID = 0x01, /// 626 FE_DENORMAL = 0x02, /// non-standard 627 FE_DIVBYZERO = 0x04, /// 628 FE_OVERFLOW = 0x08, /// 629 FE_UNDERFLOW = 0x10, /// 630 FE_INEXACT = 0x20, /// 631 FE_ALL_EXCEPT = 0x3F, /// 632 } 633 634 // The ix87 FPU supports all of the four defined rounding modes. 635 enum 636 { 637 FE_TONEAREST = 0, /// 638 FE_DOWNWARD = 0x400, /// 639 FE_UPWARD = 0x800, /// 640 FE_TOWARDZERO = 0xC00, /// 641 } 642 } 643 else version (X86_64) 644 { 645 // Define bits representing the exception. 646 enum 647 { 648 FE_INVALID = 0x01, /// 649 FE_DENORMAL = 0x02, /// non-standard 650 FE_DIVBYZERO = 0x04, /// 651 FE_OVERFLOW = 0x08, /// 652 FE_UNDERFLOW = 0x10, /// 653 FE_INEXACT = 0x20, /// 654 FE_ALL_EXCEPT = 0x3F, /// 655 } 656 657 // The ix87 FPU supports all of the four defined rounding modes. 658 enum 659 { 660 FE_TONEAREST = 0, /// 661 FE_DOWNWARD = 0x400, /// 662 FE_UPWARD = 0x800, /// 663 FE_TOWARDZERO = 0xC00, /// 664 } 665 } 666 else version (ARM_Any) 667 { 668 // Define bits representing exceptions in the FPU status word. 669 enum 670 { 671 FE_INVALID = 1, /// 672 FE_DIVBYZERO = 2, /// 673 FE_OVERFLOW = 4, /// 674 FE_UNDERFLOW = 8, /// 675 FE_INEXACT = 16, /// 676 FE_ALL_EXCEPT = 31, /// 677 } 678 679 // VFP supports all of the four defined rounding modes. 680 enum 681 { 682 FE_TONEAREST = 0, /// 683 FE_UPWARD = 0x400000, /// 684 FE_DOWNWARD = 0x800000, /// 685 FE_TOWARDZERO = 0xC00000, /// 686 } 687 } 688 else version (HPPA_Any) 689 { 690 // Define bits representing the exception. 691 enum 692 { 693 FE_INEXACT = 0x01, /// 694 FE_UNDERFLOW = 0x02, /// 695 FE_OVERFLOW = 0x04, /// 696 FE_DIVBYZERO = 0x08, /// 697 FE_INVALID = 0x10, /// 698 FE_ALL_EXCEPT = 0x1F, /// 699 } 700 701 // The HPPA FPU supports all of the four defined rounding modes. 702 enum 703 { 704 FE_TONEAREST = 0x0, /// 705 FE_TOWARDZERO = 0x200, /// 706 FE_UPWARD = 0x400, /// 707 FE_DOWNWARD = 0x600, /// 708 } 709 } 710 else version (MIPS_Any) 711 { 712 // Define bits representing the exception. 713 enum 714 { 715 FE_INEXACT = 0x04, /// 716 FE_UNDERFLOW = 0x08, /// 717 FE_OVERFLOW = 0x10, /// 718 FE_DIVBYZERO = 0x20, /// 719 FE_INVALID = 0x40, /// 720 FE_ALL_EXCEPT = 0x7C, /// 721 } 722 723 // The MIPS FPU supports all of the four defined rounding modes. 724 enum 725 { 726 FE_TONEAREST = 0x0, /// 727 FE_TOWARDZERO = 0x1, /// 728 FE_UPWARD = 0x2, /// 729 FE_DOWNWARD = 0x3, /// 730 } 731 } 732 else version (PPC_Any) 733 { 734 // Define bits representing the exception. 735 enum 736 { 737 FE_INEXACT = 0x2000000, /// 738 FE_DIVBYZERO = 0x4000000, /// 739 FE_UNDERFLOW = 0x8000000, /// 740 FE_OVERFLOW = 0x10000000, /// 741 FE_INVALID = 0x20000000, /// 742 FE_INVALID_SNAN = 0x1000000, /// non-standard 743 FE_INVALID_ISI = 0x800000, /// non-standard 744 FE_INVALID_IDI = 0x400000, /// non-standard 745 FE_INVALID_ZDZ = 0x200000, /// non-standard 746 FE_INVALID_IMZ = 0x100000, /// non-standard 747 FE_INVALID_COMPARE = 0x80000, /// non-standard 748 FE_INVALID_SOFTWARE = 0x400, /// non-standard 749 FE_INVALID_SQRT = 0x200, /// non-standard 750 FE_INVALID_INTEGER_CONVERSION = 0x100, /// non-standard 751 FE_ALL_INVALID = 0x1F80700, /// non-standard 752 FE_ALL_EXCEPT = 0x3E000000, /// 753 } 754 755 // PowerPC chips support all of the four defined rounding modes. 756 enum 757 { 758 FE_TONEAREST = 0, /// 759 FE_TOWARDZERO = 1, /// 760 FE_UPWARD = 2, /// 761 FE_DOWNWARD = 3, /// 762 } 763 } 764 else version (RISCV_Any) 765 { 766 // Define bits representing exceptions in the FPSR status word. 767 enum 768 { 769 FE_INEXACT = 0x01, /// 770 FE_UNDERFLOW = 0x02, /// 771 FE_OVERFLOW = 0x04, /// 772 FE_DIVBYZERO = 0x08, /// 773 FE_INVALID = 0x10, /// 774 FE_ALL_EXCEPT = 0x1f, /// 775 } 776 777 // Define bits representing rounding modes in the FPCR Rmode field. 778 enum 779 { 780 FE_TONEAREST = 0x0, /// 781 FE_TOWARDZERO = 0x1, /// 782 FE_DOWNWARD = 0x2, /// 783 FE_UPWARD = 0x3, /// 784 } 785 } 786 else version (SPARC_Any) 787 { 788 // Define bits representing the exception. 789 enum 790 { 791 FE_INVALID = 0x200, /// 792 FE_OVERFLOW = 0x100, /// 793 FE_UNDERFLOW = 0x80, /// 794 FE_DIVBYZERO = 0x40, /// 795 FE_INEXACT = 0x20, /// 796 FE_ALL_EXCEPT = 0x3E0, /// 797 } 798 799 // The Sparc FPU supports all of the four defined rounding modes. 800 enum 801 { 802 FE_TONEAREST = 0x0, /// 803 FE_TOWARDZERO = 0x40000000, /// 804 FE_UPWARD = 0x80000000, /// 805 FE_DOWNWARD = 0xc0000000, /// 806 } 807 } 808 else version (IBMZ_Any) 809 { 810 // Define bits representing the exception. 811 enum 812 { 813 FE_INVALID = 0x80, /// 814 FE_DIVBYZERO = 0x40, /// 815 FE_OVERFLOW = 0x20, /// 816 FE_UNDERFLOW = 0x10, /// 817 FE_INEXACT = 0x08, /// 818 FE_ALL_EXCEPT = 0xF8, /// 819 } 820 821 // SystemZ supports all of the four defined rounding modes. 822 enum 823 { 824 FE_TONEAREST = 0x0, /// 825 FE_DOWNWARD = 0x3, /// 826 FE_UPWARD = 0x2, /// 827 FE_TOWARDZERO = 0x1, /// 828 } 829 } 830 else version (LoongArch64) 831 { 832 // Define bits representing exceptions in the Flags field in FCSR{0,2}. 833 enum 834 { 835 FE_INEXACT = 0x010000, /// 836 FE_UNDERFLOW = 0x020000, /// 837 FE_OVERFLOW = 0x040000, /// 838 FE_DIVBYZERO = 0x080000, /// 839 FE_INVALID = 0x100000, /// 840 FE_ALL_EXCEPT = 0x1f0000, /// 841 } 842 843 // Define bits representing rounding modes in the RM field in FCSR{0,3}. 844 enum 845 { 846 FE_TONEAREST = 0x000, /// 847 FE_TOWARDZERO = 0x100, /// 848 FE_UPWARD = 0x200, /// 849 FE_DOWNWARD = 0x300, /// 850 } 851 } 852 else version (WebAssembly) 853 { 854 // FIXME 855 // Define bits representing the exception. 856 enum 857 { 858 FE_INVALID = 0x01, /// 859 FE_DENORMAL = 0x02, /// non-standard 860 FE_DIVBYZERO = 0x04, /// 861 FE_OVERFLOW = 0x08, /// 862 FE_UNDERFLOW = 0x10, /// 863 FE_INEXACT = 0x20, /// 864 FE_ALL_EXCEPT = 0x3F, /// 865 } 866 867 // The ix87 FPU supports all of the four defined rounding modes. 868 enum 869 { 870 FE_TONEAREST = 0, /// 871 FE_DOWNWARD = 0x400, /// 872 FE_UPWARD = 0x800, /// 873 FE_TOWARDZERO = 0xC00, /// 874 } 875 } 876 else 877 { 878 static assert(0, "Unimplemented architecture"); 879 } 880 881 } 882 883 version (GNUFP) 884 { 885 /// 886 enum FE_DFL_ENV = cast(fenv_t*)(-1); 887 } 888 else version (CRuntime_DigitalMars) 889 { 890 private extern __gshared fenv_t _FE_DFL_ENV; 891 /// 892 enum fenv_t* FE_DFL_ENV = &_FE_DFL_ENV; 893 } 894 else version (CRuntime_Microsoft) 895 { 896 private extern __gshared fenv_t _Fenv0; 897 /// 898 enum FE_DFL_ENV = &_Fenv0; 899 } 900 else version (Darwin) 901 { 902 private extern __gshared fenv_t _FE_DFL_ENV; 903 /// 904 enum FE_DFL_ENV = &_FE_DFL_ENV; 905 } 906 else version (FreeBSD) 907 { 908 private extern const fenv_t __fe_dfl_env; 909 /// 910 enum FE_DFL_ENV = &__fe_dfl_env; 911 } 912 else version (NetBSD) 913 { 914 private extern const fenv_t __fe_dfl_env; 915 /// 916 enum FE_DFL_ENV = &__fe_dfl_env; 917 } 918 else version (OpenBSD) 919 { 920 private extern const fenv_t __fe_dfl_env; 921 /// 922 enum FE_DFL_ENV = &__fe_dfl_env; 923 } 924 else version (DragonFlyBSD) 925 { 926 private extern const fenv_t __fe_dfl_env; 927 /// 928 enum FE_DFL_ENV = &__fe_dfl_env; 929 } 930 else version (CRuntime_Bionic) 931 { 932 private extern const fenv_t __fe_dfl_env; 933 /// 934 enum FE_DFL_ENV = &__fe_dfl_env; 935 } 936 else version (Solaris) 937 { 938 private extern const fenv_t __fenv_def_env; 939 /// 940 enum FE_DFL_ENV = &__fenv_def_env; 941 } 942 else version (CRuntime_Musl) 943 { 944 /// 945 enum FE_DFL_ENV = cast(fenv_t*)(-1); 946 } 947 else version (CRuntime_UClibc) 948 { 949 /// 950 enum FE_DFL_ENV = cast(fenv_t*)(-1); 951 } 952 else version (FreeStanding) 953 { 954 /// 955 enum FE_DFL_ENV = cast(fenv_t*)(-1); 956 } 957 else 958 { 959 static assert( false, "Unsupported platform" ); 960 } 961 962 /// 963 int feclearexcept(int excepts); 964 965 /// 966 int fetestexcept(int excepts); 967 /// 968 int feholdexcept(fenv_t* envp); 969 970 /// 971 int fegetexceptflag(fexcept_t* flagp, int excepts); 972 /// 973 int fesetexceptflag(const scope fexcept_t* flagp, int excepts); 974 975 /// 976 int fegetround(); 977 /// 978 int fesetround(int round); 979 980 /// 981 int fegetenv(fenv_t* envp); 982 /// 983 int fesetenv(const scope fenv_t* envp); 984 985 // MS define feraiseexcept() and feupdateenv() inline. 986 version (CRuntime_Microsoft) // supported since MSVCRT 12 (VS 2013) only 987 { 988 /// 989 int feraiseexcept()(int excepts) 990 { 991 struct Entry 992 { 993 int exceptVal; 994 double num; 995 double denom; 996 } 997 static __gshared immutable(Entry[5]) table = 998 [ // Raise exception by evaluating num / denom: 999 { FE_INVALID, 0.0, 0.0 }, 1000 { FE_DIVBYZERO, 1.0, 0.0 }, 1001 { FE_OVERFLOW, 1e+300, 1e-300 }, 1002 { FE_UNDERFLOW, 1e-300, 1e+300 }, 1003 { FE_INEXACT, 2.0, 3.0 } 1004 ]; 1005 1006 if ((excepts &= FE_ALL_EXCEPT) == 0) 1007 return 0; 1008 1009 // Raise the exceptions not masked: 1010 double ans = void; 1011 foreach (i; 0 .. table.length) 1012 { 1013 if ((excepts & table[i].exceptVal) != 0) 1014 ans = table[i].num / table[i].denom; 1015 } 1016 1017 return 0; 1018 } 1019 1020 /// 1021 int feupdateenv()(const scope fenv_t* envp) 1022 { 1023 int excepts = fetestexcept(FE_ALL_EXCEPT); 1024 return (fesetenv(envp) != 0 || feraiseexcept(excepts) != 0 ? 1 : 0); 1025 } 1026 } 1027 else 1028 { 1029 /// 1030 int feraiseexcept(int excepts); 1031 /// 1032 int feupdateenv(const scope fenv_t* envp); 1033 }