brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · 0b749ab Raw
133 lines · cpp
1#define AVOID_NATIVE_UINT128_T 12#include "flang/Common/uint128.h"3#include "flang/Testing/testing.h"4#include "llvm/Support/raw_ostream.h"5#include <cinttypes>6 7#if (defined __GNUC__ || defined __clang__) && defined __SIZEOF_INT128__8#define HAS_NATIVE_UINT128_T 19#else10#undef HAS_NATIVE_UINT128_T11#endif12 13using U128 = Fortran::common::UnsignedInt128;14 15static void Test(std::uint64_t x) {16  U128 n{x};17  MATCH(x, static_cast<std::uint64_t>(n));18  MATCH(~x, static_cast<std::uint64_t>(~n));19  MATCH(-x, static_cast<std::uint64_t>(-n));20  MATCH(!x, static_cast<std::uint64_t>(!n));21  TEST(n == n);22  TEST(n + n == n * static_cast<U128>(2));23  TEST(n - n == static_cast<U128>(0));24  TEST(n + n == n << static_cast<U128>(1));25  TEST(n + n == n << static_cast<U128>(1));26  TEST((n + n) - n == n);27  TEST(((n + n) >> static_cast<U128>(1)) == n);28  if (x != 0) {29    TEST(static_cast<U128>(0) / n == static_cast<U128>(0));30    TEST(static_cast<U128>(n - 1) / n == static_cast<U128>(0));31    TEST(static_cast<U128>(n) / n == static_cast<U128>(1));32    TEST(static_cast<U128>(n + n - 1) / n == static_cast<U128>(1));33    TEST(static_cast<U128>(n + n) / n == static_cast<U128>(2));34  }35}36 37static void Test(std::uint64_t x, std::uint64_t y) {38  U128 m{x}, n{y};39  MATCH(x, static_cast<std::uint64_t>(m));40  MATCH(y, static_cast<std::uint64_t>(n));41  MATCH(x & y, static_cast<std::uint64_t>(m & n));42  MATCH(x | y, static_cast<std::uint64_t>(m | n));43  MATCH(x ^ y, static_cast<std::uint64_t>(m ^ n));44  MATCH(x + y, static_cast<std::uint64_t>(m + n));45  MATCH(x - y, static_cast<std::uint64_t>(m - n));46  MATCH(x * y, static_cast<std::uint64_t>(m * n));47  if (n != 0) {48    MATCH(x / y, static_cast<std::uint64_t>(m / n));49  }50}51 52#if HAS_NATIVE_UINT128_T53static __uint128_t ToNative(U128 n) {54  return static_cast<__uint128_t>(static_cast<std::uint64_t>(n >> 64)) << 64 |55      static_cast<std::uint64_t>(n);56}57 58static U128 FromNative(__uint128_t n) {59  return U128{static_cast<std::uint64_t>(n >> 64)} << 64 |60      U128{static_cast<std::uint64_t>(n)};61}62 63static void TestVsNative(__uint128_t x, __uint128_t y) {64  U128 m{FromNative(x)}, n{FromNative(y)};65  TEST(ToNative(m) == x);66  TEST(ToNative(n) == y);67  TEST(ToNative(~m) == ~x);68  TEST(ToNative(-m) == -x);69  TEST(ToNative(!m) == !x);70  TEST(ToNative(m < n) == (x < y));71  TEST(ToNative(m <= n) == (x <= y));72  TEST(ToNative(m == n) == (x == y));73  TEST(ToNative(m != n) == (x != y));74  TEST(ToNative(m >= n) == (x >= y));75  TEST(ToNative(m > n) == (x > y));76  TEST(ToNative(m & n) == (x & y));77  TEST(ToNative(m | n) == (x | y));78  TEST(ToNative(m ^ n) == (x ^ y));79  if (y < 128) {80    TEST(ToNative(m << n) == (x << y));81    TEST(ToNative(m >> n) == (x >> y));82  }83  TEST(ToNative(m + n) == (x + y));84  TEST(ToNative(m - n) == (x - y));85  TEST(ToNative(m * n) == (x * y));86  if (y > 0) {87    TEST(ToNative(m / n) == (x / y));88    TEST(ToNative(m % n) == (x % y));89    TEST(ToNative(m - n * (m / n)) == (x % y));90  }91}92 93static void TestVsNative() {94  for (int j{0}; j < 128; ++j) {95    for (int k{0}; k < 128; ++k) {96      __uint128_t m{1}, n{1};97      m <<= j, n <<= k;98      TestVsNative(m, n);99      TestVsNative(~m, n);100      TestVsNative(m, ~n);101      TestVsNative(~m, ~n);102      TestVsNative(m ^ n, n);103      TestVsNative(m, m ^ n);104      TestVsNative(m ^ ~n, n);105      TestVsNative(m, ~m ^ n);106      TestVsNative(m ^ ~n, m ^ n);107      TestVsNative(m ^ n, ~m ^ n);108      TestVsNative(m ^ ~n, ~m ^ n);109      Test(m, 10000000000000000); // important case for decimal conversion110      Test(~m, 10000000000000000);111    }112  }113}114#endif115 116int main() {117  for (std::uint64_t j{0}; j < 64; ++j) {118    Test(j);119    Test(~j);120    Test(std::uint64_t(1) << j);121    for (std::uint64_t k{0}; k < 64; ++k) {122      Test(j, k);123    }124  }125#if HAS_NATIVE_UINT128_T126  llvm::outs() << "Environment has native __uint128_t\n";127  TestVsNative();128#else129  llvm::outs() << "Environment lacks native __uint128_t\n";130#endif131  return testing::Complete();132}133