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 469 else 470 { 471 static assert(false, "Architecture not supported."); 472 } 473 } 474 else version (CRuntime_UClibc) 475 { 476 version (X86) 477 { 478 struct fenv_t 479 { 480 ushort __control_word; 481 ushort __unused1; 482 ushort __status_word; 483 ushort __unused2; 484 ushort __tags; 485 ushort __unused3; 486 uint __eip; 487 ushort __cs_selector; 488 ushort __opcode; 489 uint __data_offset; 490 ushort __data_selector; 491 ushort __unused5; 492 } 493 494 alias fexcept_t = ushort; 495 } 496 else version (X86_64) 497 { 498 struct fenv_t 499 { 500 ushort __control_word; 501 ushort __unused1; 502 ushort __status_word; 503 ushort __unused2; 504 ushort __tags; 505 ushort __unused3; 506 uint __eip; 507 ushort __cs_selector; 508 ushort __opcode; 509 uint __data_offset; 510 ushort __data_selector; 511 ushort __unused5; 512 uint __mxcsr; 513 } 514 515 alias fexcept_t = ushort; 516 } 517 else version (MIPS_Any) 518 { 519 struct fenv_t 520 { 521 uint __fp_control_register; 522 } 523 524 alias fexcept_t = ushort; 525 } 526 else version (ARM) 527 { 528 struct fenv_t 529 { 530 uint __cw; 531 } 532 533 alias fexcept_t = uint; 534 } 535 else 536 { 537 static assert(false, "Architecture not supported."); 538 } 539 } 540 else version (FreeStanding) 541 { 542 struct fenv_t {} 543 alias fexcept_t = uint; 544 } 545 else 546 { 547 static assert( false, "Unsupported platform" ); 548 } 549 550 version (CRuntime_Microsoft) 551 { 552 enum 553 { 554 FE_INEXACT = 1, /// 555 FE_UNDERFLOW = 2, /// 556 FE_OVERFLOW = 4, /// 557 FE_DIVBYZERO = 8, /// 558 FE_INVALID = 0x10, /// 559 FE_ALL_EXCEPT = 0x1F, /// 560 FE_TONEAREST = 0, /// 561 FE_UPWARD = 0x100, /// 562 FE_DOWNWARD = 0x200, /// 563 FE_TOWARDZERO = 0x300, /// 564 } 565 } 566 else version (Solaris) 567 { 568 version (SPARC_Any) 569 { 570 enum 571 { 572 FE_TONEAREST = 0, 573 FE_TOWARDZERO = 1, 574 FE_UPWARD = 2, 575 FE_DOWNWARD = 3, 576 } 577 578 enum 579 { 580 FE_INEXACT = 0x01, 581 FE_DIVBYZERO = 0x02, 582 FE_UNDERFLOW = 0x04, 583 FE_OVERFLOW = 0x08, 584 FE_INVALID = 0x10, 585 FE_ALL_EXCEPT = 0x1f, 586 } 587 588 } 589 else version (X86_Any) 590 { 591 enum 592 { 593 FE_TONEAREST = 0, 594 FE_DOWNWARD = 1, 595 FE_UPWARD = 2, 596 FE_TOWARDZERO = 3, 597 } 598 599 enum 600 { 601 FE_INVALID = 0x01, 602 FE_DIVBYZERO = 0x04, 603 FE_OVERFLOW = 0x08, 604 FE_UNDERFLOW = 0x10, 605 FE_INEXACT = 0x20, 606 FE_ALL_EXCEPT = 0x3d, 607 } 608 } 609 else 610 { 611 static assert(0, "Unimplemented architecture"); 612 } 613 } 614 else 615 { 616 version (X86) 617 { 618 // Define bits representing the exception. 619 enum 620 { 621 FE_INVALID = 0x01, /// 622 FE_DENORMAL = 0x02, /// non-standard 623 FE_DIVBYZERO = 0x04, /// 624 FE_OVERFLOW = 0x08, /// 625 FE_UNDERFLOW = 0x10, /// 626 FE_INEXACT = 0x20, /// 627 FE_ALL_EXCEPT = 0x3F, /// 628 } 629 630 // The ix87 FPU supports all of the four defined rounding modes. 631 enum 632 { 633 FE_TONEAREST = 0, /// 634 FE_DOWNWARD = 0x400, /// 635 FE_UPWARD = 0x800, /// 636 FE_TOWARDZERO = 0xC00, /// 637 } 638 } 639 else version (X86_64) 640 { 641 // Define bits representing the exception. 642 enum 643 { 644 FE_INVALID = 0x01, /// 645 FE_DENORMAL = 0x02, /// non-standard 646 FE_DIVBYZERO = 0x04, /// 647 FE_OVERFLOW = 0x08, /// 648 FE_UNDERFLOW = 0x10, /// 649 FE_INEXACT = 0x20, /// 650 FE_ALL_EXCEPT = 0x3F, /// 651 } 652 653 // The ix87 FPU supports all of the four defined rounding modes. 654 enum 655 { 656 FE_TONEAREST = 0, /// 657 FE_DOWNWARD = 0x400, /// 658 FE_UPWARD = 0x800, /// 659 FE_TOWARDZERO = 0xC00, /// 660 } 661 } 662 else version (ARM_Any) 663 { 664 // Define bits representing exceptions in the FPU status word. 665 enum 666 { 667 FE_INVALID = 1, /// 668 FE_DIVBYZERO = 2, /// 669 FE_OVERFLOW = 4, /// 670 FE_UNDERFLOW = 8, /// 671 FE_INEXACT = 16, /// 672 FE_ALL_EXCEPT = 31, /// 673 } 674 675 // VFP supports all of the four defined rounding modes. 676 enum 677 { 678 FE_TONEAREST = 0, /// 679 FE_UPWARD = 0x400000, /// 680 FE_DOWNWARD = 0x800000, /// 681 FE_TOWARDZERO = 0xC00000, /// 682 } 683 } 684 else version (HPPA_Any) 685 { 686 // Define bits representing the exception. 687 enum 688 { 689 FE_INEXACT = 0x01, /// 690 FE_UNDERFLOW = 0x02, /// 691 FE_OVERFLOW = 0x04, /// 692 FE_DIVBYZERO = 0x08, /// 693 FE_INVALID = 0x10, /// 694 FE_ALL_EXCEPT = 0x1F, /// 695 } 696 697 // The HPPA FPU supports all of the four defined rounding modes. 698 enum 699 { 700 FE_TONEAREST = 0x0, /// 701 FE_TOWARDZERO = 0x200, /// 702 FE_UPWARD = 0x400, /// 703 FE_DOWNWARD = 0x600, /// 704 } 705 } 706 else version (MIPS_Any) 707 { 708 // Define bits representing the exception. 709 enum 710 { 711 FE_INEXACT = 0x04, /// 712 FE_UNDERFLOW = 0x08, /// 713 FE_OVERFLOW = 0x10, /// 714 FE_DIVBYZERO = 0x20, /// 715 FE_INVALID = 0x40, /// 716 FE_ALL_EXCEPT = 0x7C, /// 717 } 718 719 // The MIPS FPU supports all of the four defined rounding modes. 720 enum 721 { 722 FE_TONEAREST = 0x0, /// 723 FE_TOWARDZERO = 0x1, /// 724 FE_UPWARD = 0x2, /// 725 FE_DOWNWARD = 0x3, /// 726 } 727 } 728 else version (PPC_Any) 729 { 730 // Define bits representing the exception. 731 enum 732 { 733 FE_INEXACT = 0x2000000, /// 734 FE_DIVBYZERO = 0x4000000, /// 735 FE_UNDERFLOW = 0x8000000, /// 736 FE_OVERFLOW = 0x10000000, /// 737 FE_INVALID = 0x20000000, /// 738 FE_INVALID_SNAN = 0x1000000, /// non-standard 739 FE_INVALID_ISI = 0x800000, /// non-standard 740 FE_INVALID_IDI = 0x400000, /// non-standard 741 FE_INVALID_ZDZ = 0x200000, /// non-standard 742 FE_INVALID_IMZ = 0x100000, /// non-standard 743 FE_INVALID_COMPARE = 0x80000, /// non-standard 744 FE_INVALID_SOFTWARE = 0x400, /// non-standard 745 FE_INVALID_SQRT = 0x200, /// non-standard 746 FE_INVALID_INTEGER_CONVERSION = 0x100, /// non-standard 747 FE_ALL_INVALID = 0x1F80700, /// non-standard 748 FE_ALL_EXCEPT = 0x3E000000, /// 749 } 750 751 // PowerPC chips support all of the four defined rounding modes. 752 enum 753 { 754 FE_TONEAREST = 0, /// 755 FE_TOWARDZERO = 1, /// 756 FE_UPWARD = 2, /// 757 FE_DOWNWARD = 3, /// 758 } 759 } 760 else version (RISCV_Any) 761 { 762 // Define bits representing exceptions in the FPSR status word. 763 enum 764 { 765 FE_INEXACT = 0x01, /// 766 FE_UNDERFLOW = 0x02, /// 767 FE_OVERFLOW = 0x04, /// 768 FE_DIVBYZERO = 0x08, /// 769 FE_INVALID = 0x10, /// 770 FE_ALL_EXCEPT = 0x1f, /// 771 } 772 773 // Define bits representing rounding modes in the FPCR Rmode field. 774 enum 775 { 776 FE_TONEAREST = 0x0, /// 777 FE_TOWARDZERO = 0x1, /// 778 FE_DOWNWARD = 0x2, /// 779 FE_UPWARD = 0x3, /// 780 } 781 } 782 else version (SPARC_Any) 783 { 784 // Define bits representing the exception. 785 enum 786 { 787 FE_INVALID = 0x200, /// 788 FE_OVERFLOW = 0x100, /// 789 FE_UNDERFLOW = 0x80, /// 790 FE_DIVBYZERO = 0x40, /// 791 FE_INEXACT = 0x20, /// 792 FE_ALL_EXCEPT = 0x3E0, /// 793 } 794 795 // The Sparc FPU supports all of the four defined rounding modes. 796 enum 797 { 798 FE_TONEAREST = 0x0, /// 799 FE_TOWARDZERO = 0x40000000, /// 800 FE_UPWARD = 0x80000000, /// 801 FE_DOWNWARD = 0xc0000000, /// 802 } 803 } 804 else version (IBMZ_Any) 805 { 806 // Define bits representing the exception. 807 enum 808 { 809 FE_INVALID = 0x80, /// 810 FE_DIVBYZERO = 0x40, /// 811 FE_OVERFLOW = 0x20, /// 812 FE_UNDERFLOW = 0x10, /// 813 FE_INEXACT = 0x08, /// 814 FE_ALL_EXCEPT = 0xF8, /// 815 } 816 817 // SystemZ supports all of the four defined rounding modes. 818 enum 819 { 820 FE_TONEAREST = 0x0, /// 821 FE_DOWNWARD = 0x3, /// 822 FE_UPWARD = 0x2, /// 823 FE_TOWARDZERO = 0x1, /// 824 } 825 } 826 else version (LoongArch64) 827 { 828 // Define bits representing exceptions in the Flags field in FCSR{0,2}. 829 enum 830 { 831 FE_INEXACT = 0x010000, /// 832 FE_UNDERFLOW = 0x020000, /// 833 FE_OVERFLOW = 0x040000, /// 834 FE_DIVBYZERO = 0x080000, /// 835 FE_INVALID = 0x100000, /// 836 FE_ALL_EXCEPT = 0x1f0000, /// 837 } 838 839 // Define bits representing rounding modes in the RM field in FCSR{0,3}. 840 enum 841 { 842 FE_TONEAREST = 0x000, /// 843 FE_TOWARDZERO = 0x100, /// 844 FE_UPWARD = 0x200, /// 845 FE_DOWNWARD = 0x300, /// 846 } 847 } 848 else version (WebAssembly) 849 { 850 // FIXME 851 // Define bits representing the exception. 852 enum 853 { 854 FE_INVALID = 0x01, /// 855 FE_DENORMAL = 0x02, /// non-standard 856 FE_DIVBYZERO = 0x04, /// 857 FE_OVERFLOW = 0x08, /// 858 FE_UNDERFLOW = 0x10, /// 859 FE_INEXACT = 0x20, /// 860 FE_ALL_EXCEPT = 0x3F, /// 861 } 862 863 // The ix87 FPU supports all of the four defined rounding modes. 864 enum 865 { 866 FE_TONEAREST = 0, /// 867 FE_DOWNWARD = 0x400, /// 868 FE_UPWARD = 0x800, /// 869 FE_TOWARDZERO = 0xC00, /// 870 } 871 } 872 else 873 { 874 static assert(0, "Unimplemented architecture"); 875 } 876 877 } 878 879 version (GNUFP) 880 { 881 /// 882 enum FE_DFL_ENV = cast(fenv_t*)(-1); 883 } 884 else version (CRuntime_DigitalMars) 885 { 886 private extern __gshared fenv_t _FE_DFL_ENV; 887 /// 888 enum fenv_t* FE_DFL_ENV = &_FE_DFL_ENV; 889 } 890 else version (CRuntime_Microsoft) 891 { 892 private extern __gshared fenv_t _Fenv0; 893 /// 894 enum FE_DFL_ENV = &_Fenv0; 895 } 896 else version (Darwin) 897 { 898 private extern __gshared fenv_t _FE_DFL_ENV; 899 /// 900 enum FE_DFL_ENV = &_FE_DFL_ENV; 901 } 902 else version (FreeBSD) 903 { 904 private extern const fenv_t __fe_dfl_env; 905 /// 906 enum FE_DFL_ENV = &__fe_dfl_env; 907 } 908 else version (NetBSD) 909 { 910 private extern const fenv_t __fe_dfl_env; 911 /// 912 enum FE_DFL_ENV = &__fe_dfl_env; 913 } 914 else version (OpenBSD) 915 { 916 private extern const fenv_t __fe_dfl_env; 917 /// 918 enum FE_DFL_ENV = &__fe_dfl_env; 919 } 920 else version (DragonFlyBSD) 921 { 922 private extern const fenv_t __fe_dfl_env; 923 /// 924 enum FE_DFL_ENV = &__fe_dfl_env; 925 } 926 else version (CRuntime_Bionic) 927 { 928 private extern const fenv_t __fe_dfl_env; 929 /// 930 enum FE_DFL_ENV = &__fe_dfl_env; 931 } 932 else version (Solaris) 933 { 934 private extern const fenv_t __fenv_def_env; 935 /// 936 enum FE_DFL_ENV = &__fenv_def_env; 937 } 938 else version (CRuntime_Musl) 939 { 940 /// 941 enum FE_DFL_ENV = cast(fenv_t*)(-1); 942 } 943 else version (CRuntime_UClibc) 944 { 945 /// 946 enum FE_DFL_ENV = cast(fenv_t*)(-1); 947 } 948 else version (FreeStanding) 949 { 950 /// 951 enum FE_DFL_ENV = cast(fenv_t*)(-1); 952 } 953 else 954 { 955 static assert( false, "Unsupported platform" ); 956 } 957 958 /// 959 int feclearexcept(int excepts); 960 961 /// 962 int fetestexcept(int excepts); 963 /// 964 int feholdexcept(fenv_t* envp); 965 966 /// 967 int fegetexceptflag(fexcept_t* flagp, int excepts); 968 /// 969 int fesetexceptflag(const scope fexcept_t* flagp, int excepts); 970 971 /// 972 int fegetround(); 973 /// 974 int fesetround(int round); 975 976 /// 977 int fegetenv(fenv_t* envp); 978 /// 979 int fesetenv(const scope fenv_t* envp); 980 981 // MS define feraiseexcept() and feupdateenv() inline. 982 version (CRuntime_Microsoft) // supported since MSVCRT 12 (VS 2013) only 983 { 984 /// 985 int feraiseexcept()(int excepts) 986 { 987 struct Entry 988 { 989 int exceptVal; 990 double num; 991 double denom; 992 } 993 static __gshared immutable(Entry[5]) table = 994 [ // Raise exception by evaluating num / denom: 995 { FE_INVALID, 0.0, 0.0 }, 996 { FE_DIVBYZERO, 1.0, 0.0 }, 997 { FE_OVERFLOW, 1e+300, 1e-300 }, 998 { FE_UNDERFLOW, 1e-300, 1e+300 }, 999 { FE_INEXACT, 2.0, 3.0 } 1000 ]; 1001 1002 if ((excepts &= FE_ALL_EXCEPT) == 0) 1003 return 0; 1004 1005 // Raise the exceptions not masked: 1006 double ans = void; 1007 foreach (i; 0 .. table.length) 1008 { 1009 if ((excepts & table[i].exceptVal) != 0) 1010 ans = table[i].num / table[i].denom; 1011 } 1012 1013 return 0; 1014 } 1015 1016 /// 1017 int feupdateenv()(const scope fenv_t* envp) 1018 { 1019 int excepts = fetestexcept(FE_ALL_EXCEPT); 1020 return (fesetenv(envp) != 0 || feraiseexcept(excepts) != 0 ? 1 : 0); 1021 } 1022 } 1023 else 1024 { 1025 /// 1026 int feraiseexcept(int excepts); 1027 /// 1028 int feupdateenv(const scope fenv_t* envp); 1029 }