#include "prx/libc/include/Api.hpp" #include #include #include #include #include #include #include namespace { struct Case { unsigned function; unsigned rounding; unsigned denormals; std::uint64_t first; std::uint64_t second; std::uint64_t result; unsigned flags; }; constexpr Case Cases[] = { {0, 0, 0, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 0, 0, 0x0000000000000000ull, 0x0000000000000000ull, 0xfff8000000000000ull, 1u}, {0, 0, 1, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 0, 1, 0x3ff0000000000000ull, 0x0000000000000000ull, 0x7ff0000000000000ull, 4u}, {0, 0, 2, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 0, 2, 0xbff0000000000000ull, 0x0000000000000000ull, 0xfff0000000000000ull, 4u}, {0, 0, 3, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 0, 3, 0x0000000000000000ull, 0xbff0000000000000ull, 0x8000000000000000ull, 0u}, {0, 1, 0, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 1, 0, 0x7ff0000000000001ull, 0x3ff0000000000000ull, 0x7ff8000000000001ull, 1u}, {0, 1, 1, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 1, 1, 0x7ff8000000001234ull, 0xfff8000000005678ull, 0x7ff8000000001234ull, 0u}, {0, 1, 2, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 1, 2, 0xfff8000000005678ull, 0x7ff8000000001234ull, 0xfff8000000005678ull, 0u}, {0, 1, 3, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 1, 3, 0x0000000000000001ull, 0xbff0000000000000ull, 0x8000000000000000ull, 0u}, {0, 2, 0, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555556ull, 32u}, {0, 2, 0, 0x7fefffffffffffffull, 0x3fd0000000000000ull, 0x7ff0000000000000ull, 40u}, {0, 2, 1, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555556ull, 32u}, {0, 2, 1, 0x3fd0000000000000ull, 0x7fefffffffffffffull, 0x0001000000000001ull, 48u}, {0, 2, 2, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555556ull, 32u}, {0, 2, 2, 0x0000000000000000ull, 0x0000000000000000ull, 0xfff8000000000000ull, 1u}, {0, 2, 3, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555556ull, 32u}, {0, 2, 3, 0x3ff0000000000000ull, 0x0000000000000000ull, 0x7ff0000000000000ull, 4u}, {0, 3, 0, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 3, 0, 0xbff0000000000000ull, 0x0000000000000000ull, 0xfff0000000000000ull, 4u}, {0, 3, 1, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 3, 1, 0x0000000000000000ull, 0xbff0000000000000ull, 0x8000000000000000ull, 0u}, {0, 3, 2, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 3, 2, 0x7ff0000000000001ull, 0x3ff0000000000000ull, 0x7ff8000000000001ull, 1u}, {0, 3, 3, 0x3ff0000000000000ull, 0x4008000000000000ull, 0x3fd5555555555555ull, 32u}, {0, 3, 3, 0x7ff8000000001234ull, 0xfff8000000005678ull, 0x7ff8000000001234ull, 0u}, {1, 0, 0, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaabull, 32u}, {1, 0, 0, 0x0000000000000000ull, 0x0000000000000000ull, 0x00000000ffc00000ull, 1u}, {1, 0, 1, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaabull, 32u}, {1, 0, 1, 0x000000003f800000ull, 0x0000000000000000ull, 0x000000007f800000ull, 4u}, {1, 0, 2, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaabull, 32u}, {1, 0, 2, 0x00000000bf800000ull, 0x0000000000000000ull, 0x00000000ff800000ull, 4u}, {1, 0, 3, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaabull, 32u}, {1, 0, 3, 0x0000000000000000ull, 0x00000000bf800000ull, 0x0000000080000000ull, 0u}, {1, 1, 0, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaaaull, 32u}, {1, 1, 0, 0x000000007f800001ull, 0x000000003f800000ull, 0x000000007fc00001ull, 1u}, {1, 1, 1, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaaaull, 32u}, {1, 1, 1, 0x000000007fc01234ull, 0x00000000ffc05678ull, 0x000000007fc01234ull, 0u}, {1, 1, 2, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaaaull, 32u}, {1, 1, 2, 0x00000000ffc05678ull, 0x000000007fc01234ull, 0x00000000ffc05678ull, 0u}, {1, 1, 3, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaaaull, 32u}, {1, 1, 3, 0x0000000000000001ull, 0x00000000bf800000ull, 0x0000000080000000ull, 0u}, {1, 2, 0, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaabull, 32u}, {1, 2, 0, 0x000000007f7fffffull, 0x000000003e800000ull, 0x000000007f800000ull, 40u}, {1, 2, 1, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaabull, 32u}, {1, 2, 1, 0x000000003e800000ull, 0x000000007f7fffffull, 0x0000000000080001ull, 48u}, {1, 2, 2, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaabull, 32u}, {1, 2, 2, 0x0000000000000000ull, 0x0000000000000000ull, 0x00000000ffc00000ull, 1u}, {1, 2, 3, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaabull, 32u}, {1, 2, 3, 0x000000003f800000ull, 0x0000000000000000ull, 0x000000007f800000ull, 4u}, {1, 3, 0, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaaaull, 32u}, {1, 3, 0, 0x00000000bf800000ull, 0x0000000000000000ull, 0x00000000ff800000ull, 4u}, {1, 3, 1, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaaaull, 32u}, {1, 3, 1, 0x0000000000000000ull, 0x00000000bf800000ull, 0x0000000080000000ull, 0u}, {1, 3, 2, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaaaull, 32u}, {1, 3, 2, 0x000000007f800001ull, 0x000000003f800000ull, 0x000000007fc00001ull, 1u}, {1, 3, 3, 0x000000003f800000ull, 0x0000000040400000ull, 0x000000003eaaaaaaull, 32u}, {1, 3, 3, 0x000000007fc01234ull, 0x00000000ffc05678ull, 0x000000007fc01234ull, 0u}, {2, 0, 0, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 0, 0, 0x0000000000000000ull, 0x0000000000000000ull, 0x7ff0000000000000ull, 4u}, {2, 0, 1, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 0, 1, 0x8000000000000000ull, 0x0000000000000000ull, 0xfff0000000000000ull, 4u}, {2, 0, 2, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 0, 2, 0x0000000000000001ull, 0x0000000000000000ull, 0x7ff0000000000000ull, 42u}, {2, 0, 3, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 0, 3, 0x000fffffffffffffull, 0x0000000000000000ull, 0x7ff0000000000000ull, 4u}, {2, 1, 0, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 1, 0, 0x0010000000000000ull, 0x0000000000000000ull, 0x7fd0000000000000ull, 0u}, {2, 1, 1, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 1, 1, 0x7fefffffffffffffull, 0x0000000000000000ull, 0x0004000000000000ull, 48u}, {2, 1, 2, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 1, 2, 0x7ff0000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0u}, {2, 1, 3, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 1, 3, 0x7ff0000000000001ull, 0x0000000000000000ull, 0x7ff8000000000001ull, 1u}, {2, 2, 0, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555556ull, 32u}, {2, 2, 0, 0x7ff8000000001234ull, 0x0000000000000000ull, 0x7ff8000000001234ull, 0u}, {2, 2, 1, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555556ull, 32u}, {2, 2, 1, 0xfff8000000005678ull, 0x0000000000000000ull, 0xfff8000000005678ull, 0u}, {2, 2, 2, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555556ull, 32u}, {2, 2, 2, 0x0000000000000000ull, 0x0000000000000000ull, 0x7ff0000000000000ull, 4u}, {2, 2, 3, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555556ull, 32u}, {2, 2, 3, 0x8000000000000000ull, 0x0000000000000000ull, 0xfff0000000000000ull, 4u}, {2, 3, 0, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 3, 0, 0x0000000000000001ull, 0x0000000000000000ull, 0x7fefffffffffffffull, 42u}, {2, 3, 1, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 3, 1, 0x000fffffffffffffull, 0x0000000000000000ull, 0x7ff0000000000000ull, 4u}, {2, 3, 2, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 3, 2, 0x0010000000000000ull, 0x0000000000000000ull, 0x7fd0000000000000ull, 0u}, {2, 3, 3, 0x4008000000000000ull, 0x0000000000000000ull, 0x3fd5555555555555ull, 32u}, {2, 3, 3, 0x7fefffffffffffffull, 0x0000000000000000ull, 0x0000000000000000ull, 48u}, {3, 0, 0, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaabull, 32u}, {3, 0, 0, 0x0000000000000000ull, 0x0000000000000000ull, 0x000000007f800000ull, 4u}, {3, 0, 1, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaabull, 32u}, {3, 0, 1, 0x0000000080000000ull, 0x0000000000000000ull, 0x00000000ff800000ull, 4u}, {3, 0, 2, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaabull, 32u}, {3, 0, 2, 0x0000000000000001ull, 0x0000000000000000ull, 0x000000007f800000ull, 42u}, {3, 0, 3, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaabull, 32u}, {3, 0, 3, 0x00000000007fffffull, 0x0000000000000000ull, 0x000000007f800000ull, 4u}, {3, 1, 0, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaaaull, 32u}, {3, 1, 0, 0x0000000000800000ull, 0x0000000000000000ull, 0x000000007e800000ull, 0u}, {3, 1, 1, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaaaull, 32u}, {3, 1, 1, 0x000000007f7fffffull, 0x0000000000000000ull, 0x0000000000200000ull, 48u}, {3, 1, 2, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaaaull, 32u}, {3, 1, 2, 0x000000007f800000ull, 0x0000000000000000ull, 0x0000000000000000ull, 0u}, {3, 1, 3, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaaaull, 32u}, {3, 1, 3, 0x000000007f800001ull, 0x0000000000000000ull, 0x000000007fc00001ull, 1u}, {3, 2, 0, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaabull, 32u}, {3, 2, 0, 0x000000007fc01234ull, 0x0000000000000000ull, 0x000000007fc01234ull, 0u}, {3, 2, 1, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaabull, 32u}, {3, 2, 1, 0x00000000ffc05678ull, 0x0000000000000000ull, 0x00000000ffc05678ull, 0u}, {3, 2, 2, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaabull, 32u}, {3, 2, 2, 0x0000000000000000ull, 0x0000000000000000ull, 0x000000007f800000ull, 4u}, {3, 2, 3, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaabull, 32u}, {3, 2, 3, 0x0000000080000000ull, 0x0000000000000000ull, 0x00000000ff800000ull, 4u}, {3, 3, 0, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaaaull, 32u}, {3, 3, 0, 0x0000000000000001ull, 0x0000000000000000ull, 0x000000007f7fffffull, 42u}, {3, 3, 1, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaaaull, 32u}, {3, 3, 1, 0x00000000007fffffull, 0x0000000000000000ull, 0x000000007f800000ull, 4u}, {3, 3, 2, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaaaull, 32u}, {3, 3, 2, 0x0000000000800000ull, 0x0000000000000000ull, 0x000000007e800000ull, 0u}, {3, 3, 3, 0x0000000040400000ull, 0x0000000000000000ull, 0x000000003eaaaaaaull, 32u}, {3, 3, 3, 0x000000007f7fffffull, 0x0000000000000000ull, 0x0000000000000000ull, 48u}, }; int StandardFlags(unsigned flags) { return ((flags & 1u) ? FE_INVALID : 0) | ((flags & 4u) ? FE_DIVBYZERO : 0) | ((flags & 8u) ? FE_OVERFLOW : 0) | ((flags & 16u) ? FE_UNDERFLOW : 0) | ((flags & 32u) ? FE_INEXACT : 0); } } int main() { std::fenv_t saved; if (std::fegetenv(&saved) != 0) return 1; const auto savedCsr = _mm_getcsr(); const int savedError = *__error_nid_postfix(); unsigned index = 0; for (const auto& test : Cases) { for (unsigned sticky : {0u, 5u, 32u}) { if (std::fesetenv(FE_DFL_ENV) != 0) return 1; const unsigned control = 0x1f80u | (test.rounding << 13u) | ((test.denormals & 1u) ? 0x40u : 0u) | ((test.denormals & 2u) ? 0x8000u : 0u); *__error_nid_postfix() = 97; _mm_setcsr(control | sticky); std::uint64_t result = 0; if (test.function == 0) result = std::bit_cast(_Divide_nid_postfix(std::bit_cast(test.first), std::bit_cast(test.second))); else if (test.function == 1) result = std::bit_cast(_FDivide_nid_postfix(std::bit_cast(static_cast(test.first)), std::bit_cast(static_cast(test.second)))); else if (test.function == 2) result = std::bit_cast(_Recip_nid_postfix(std::bit_cast(test.first))); else result = std::bit_cast(_FRecip_nid_postfix(std::bit_cast(static_cast(test.first)))); const unsigned csr = _mm_getcsr(); const int flags = std::fetestexcept(FE_ALL_EXCEPT); const int error = *__error_nid_postfix(); if (result != test.result || csr != (control | test.flags | sticky) || flags != StandardFlags(test.flags | sticky) || error != 97) { std::fprintf(stderr, "Dinkumware division case %u sticky %u: bits %016llx/%016llx csr %x/%x flags %x/%x errno %d\n", index, sticky, static_cast(result), static_cast(test.result), csr, control | test.flags | sticky, flags, StandardFlags(test.flags | sticky), error); return 1; } } ++index; } if (std::fesetenv(&saved) != 0) return 1; _mm_setcsr(savedCsr); *__error_nid_postfix() = savedError; }