mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-04 13:07:32 +00:00
193 lines
14 KiB
C++
193 lines
14 KiB
C++
#include "prx/libc/include/Api.hpp"
|
|
#include <bit>
|
|
#include <cfenv>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <initializer_list>
|
|
#include <xmmintrin.h>
|
|
|
|
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<std::uint64_t>(_Divide_nid_postfix(std::bit_cast<double>(test.first), std::bit_cast<double>(test.second)));
|
|
else if (test.function == 1) result = std::bit_cast<std::uint32_t>(_FDivide_nid_postfix(std::bit_cast<float>(static_cast<std::uint32_t>(test.first)), std::bit_cast<float>(static_cast<std::uint32_t>(test.second))));
|
|
else if (test.function == 2) result = std::bit_cast<std::uint64_t>(_Recip_nid_postfix(std::bit_cast<double>(test.first)));
|
|
else result = std::bit_cast<std::uint32_t>(_FRecip_nid_postfix(std::bit_cast<float>(static_cast<std::uint32_t>(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<unsigned long long>(result), static_cast<unsigned long long>(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;
|
|
}
|