tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

testInt128.cpp (17262B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifdef JS_HAS_INTL_API
      6 
      7 #  include "mozilla/Compiler.h"
      8 #  include "mozilla/TextUtils.h"
      9 
     10 #  include <array>
     11 #  include <climits>
     12 #  include <cstdlib>
     13 #  include <limits>
     14 #  include <optional>
     15 #  include <stdint.h>
     16 
     17 #  include "jsapi-tests/tests.h"
     18 #  include "vm/Int128.h"
     19 
     20 // Use static_assert in compilers which support CWG2518. In all other cases
     21 // fall back to std::abort().
     22 //
     23 // https://cplusplus.github.io/CWG/issues/2518.html
     24 #  if defined(__clang__)
     25 #    define UINT128_PARSE_ERROR(...) static_assert(false, __VA_ARGS__)
     26 #  elif MOZ_IS_GCC
     27 #    if MOZ_GCC_VERSION_AT_LEAST(13, 1, 0)
     28 #      define UINT128_PARSE_ERROR(...) static_assert(false, __VA_ARGS__)
     29 #    endif
     30 #  endif
     31 #  ifndef UINT128_PARSE_ERROR
     32 #    define UINT128_PARSE_ERROR(...) std::abort()
     33 #  endif
     34 
     35 using namespace js;
     36 
     37 // Simple Uint128 parser.
     38 template <char... DIGITS>
     39 constexpr Uint128 operator""_u128() {
     40  static_assert(sizeof...(DIGITS) > 0);
     41 
     42  constexpr auto digits = std::array{DIGITS...};
     43 
     44  constexpr auto isBinaryDigit = [](auto c) {
     45    return (c >= '0' && c <= '1') || c == '\'';
     46  };
     47 
     48  constexpr auto isOctalDigit = [](auto c) {
     49    return (c >= '0' && c <= '7') || c == '\'';
     50  };
     51 
     52  constexpr auto isDigit = [](auto c) {
     53    return mozilla::IsAsciiDigit(c) || c == '\'';
     54  };
     55 
     56  constexpr auto isHexDigit = [](auto c) {
     57    return mozilla::IsAsciiHexDigit(c) || c == '\'';
     58  };
     59 
     60  constexpr auto isBinary = [isBinaryDigit](auto zero, auto prefix,
     61                                            auto... rest) {
     62    return zero == '0' && (prefix == 'b' || prefix == 'B') &&
     63           (isBinaryDigit(rest) && ...);
     64  };
     65 
     66  constexpr auto isHex = [isHexDigit](auto zero, auto prefix, auto... rest) {
     67    return zero == '0' && (prefix == 'x' || prefix == 'X') &&
     68           (isHexDigit(rest) && ...);
     69  };
     70 
     71  constexpr auto binary = [digits]() -> std::optional<Uint128> {
     72    auto value = Uint128{};
     73    for (size_t i = 2; i < digits.size(); ++i) {
     74      auto digit = digits[i];
     75      if (digit == '\'') {
     76        continue;
     77      }
     78 
     79      // Detect overflow.
     80      if (((value << 1) >> 1) != value) {
     81        return std::nullopt;
     82      }
     83      value = (value << 1) | Uint128{uint64_t(digit - '0')};
     84    }
     85    return value;
     86  };
     87 
     88  constexpr auto octal = [digits]() -> std::optional<Uint128> {
     89    auto value = Uint128{};
     90    for (size_t i = 1; i < digits.size(); ++i) {
     91      auto digit = digits[i];
     92      if (digit == '\'') {
     93        continue;
     94      }
     95 
     96      // Detect overflow.
     97      if (((value << 3) >> 3) != value) {
     98        return std::nullopt;
     99      }
    100      value = (value << 3) | Uint128{uint64_t(digit - '0')};
    101    }
    102    return value;
    103  };
    104 
    105  constexpr auto decimal = [digits]() -> std::optional<Uint128> {
    106    auto value = Uint128{};
    107    for (size_t i = 0; i < digits.size(); ++i) {
    108      auto digit = digits[i];
    109      if (digit == '\'') {
    110        continue;
    111      }
    112 
    113      // NB: Overflow check not implemented.
    114      value = (value * Uint128{10}) + Uint128{uint64_t(digit - '0')};
    115    }
    116    return value;
    117  };
    118 
    119  constexpr auto hexadecimal = [digits]() -> std::optional<Uint128> {
    120    auto value = Uint128{};
    121    for (size_t i = 2; i < digits.size(); ++i) {
    122      auto digit = digits[i];
    123      if (digit == '\'') {
    124        continue;
    125      }
    126 
    127      // Detect overflow.
    128      if (((value << 4) >> 4) != value) {
    129        return std::nullopt;
    130      }
    131      value =
    132          (value << 4) | Uint128{uint64_t(digit >= 'a'   ? (digit - 'a') + 10
    133                                          : digit >= 'A' ? (digit - 'A') + 10
    134                                                         : digit - '0')};
    135    }
    136    return value;
    137  };
    138 
    139  if constexpr (digits.size() > 2 && digits[0] == '0' &&
    140                !mozilla::IsAsciiDigit(digits[1])) {
    141    if constexpr (isBinary(DIGITS...)) {
    142      if constexpr (constexpr auto value = binary()) {
    143        return *value;
    144      } else {
    145        UINT128_PARSE_ERROR("binary literal too large");
    146      }
    147    } else if constexpr (isHex(DIGITS...)) {
    148      if constexpr (constexpr auto value = hexadecimal()) {
    149        return *value;
    150      } else {
    151        UINT128_PARSE_ERROR("hexadecimal literal too large");
    152      }
    153    } else {
    154      UINT128_PARSE_ERROR("invalid prefix literal");
    155    }
    156  } else if constexpr (digits.size() > 1 && digits[0] == '0') {
    157    if constexpr ((isOctalDigit(DIGITS) && ...)) {
    158      if constexpr (constexpr auto value = octal()) {
    159        return *value;
    160      } else {
    161        UINT128_PARSE_ERROR("octal literal too large");
    162      }
    163    } else {
    164      UINT128_PARSE_ERROR("invalid octal literal");
    165    }
    166  } else if constexpr ((isDigit(DIGITS) && ...)) {
    167    if constexpr (constexpr auto value = decimal()) {
    168      return *value;
    169    } else {
    170      UINT128_PARSE_ERROR("decimal literal too large");
    171    }
    172  } else {
    173    UINT128_PARSE_ERROR("invalid literal");
    174  }
    175 }
    176 
    177 template <char... DIGITS>
    178 constexpr Int128 operator""_i128() {
    179  return Int128{operator""_u128 < DIGITS...>()};
    180 }
    181 
    182 class ConversionFixture : public JSAPIRuntimeTest {
    183 public:
    184  virtual ~ConversionFixture() = default;
    185 
    186  template <typename T, typename U, size_t N>
    187  bool testConversion(const std::array<U, N>& values);
    188 };
    189 
    190 template <typename T, typename U, size_t N>
    191 bool ConversionFixture::testConversion(const std::array<U, N>& values) {
    192  for (auto v : values) {
    193    // Conversion to signed int.
    194    CHECK_EQUAL(int64_t(T{v}), int64_t(v));
    195    CHECK_EQUAL(int32_t(T{v}), int32_t(v));
    196    CHECK_EQUAL(int16_t(T{v}), int16_t(v));
    197    CHECK_EQUAL(int8_t(T{v}), int8_t(v));
    198 
    199    // Conversion to unsigned int.
    200    CHECK_EQUAL(uint64_t(T{v}), uint64_t(v));
    201    CHECK_EQUAL(uint32_t(T{v}), uint32_t(v));
    202    CHECK_EQUAL(uint16_t(T{v}), uint16_t(v));
    203    CHECK_EQUAL(uint8_t(T{v}), uint8_t(v));
    204 
    205    // Conversion to double.
    206    CHECK_EQUAL(double(T{v}), double(v));
    207 
    208    // Conversion to bool.
    209    CHECK_EQUAL(bool(T{v}), bool(v));
    210  }
    211  return true;
    212 }
    213 
    214 BEGIN_FIXTURE_TEST(ConversionFixture, testInt128_conversion) {
    215  auto values = std::array{
    216      INT64_MIN,
    217      INT64_MIN + 1,
    218      int64_t(INT32_MIN) - 1,
    219      int64_t(INT32_MIN),
    220      int64_t(INT32_MIN) + 1,
    221      int64_t(-1),
    222      int64_t(0),
    223      int64_t(1),
    224      int64_t(INT32_MAX) - 1,
    225      int64_t(INT32_MAX),
    226      int64_t(INT32_MAX) + 1,
    227      INT64_MAX - 1,
    228      INT64_MAX,
    229  };
    230 
    231  CHECK(testConversion<Int128>(values));
    232 
    233  return true;
    234 }
    235 END_FIXTURE_TEST(ConversionFixture, testInt128_conversion)
    236 
    237 BEGIN_FIXTURE_TEST(ConversionFixture, testUint128_conversion) {
    238  auto values = std::array{
    239      uint64_t(0),
    240      uint64_t(1),
    241      uint64_t(UINT32_MAX) - 1,
    242      uint64_t(UINT32_MAX),
    243      uint64_t(UINT32_MAX) + 1,
    244      UINT64_MAX - 1,
    245      UINT64_MAX,
    246  };
    247 
    248  CHECK(testConversion<Uint128>(values));
    249 
    250  return true;
    251 }
    252 END_FIXTURE_TEST(ConversionFixture, testUint128_conversion)
    253 
    254 class OperatorFixture : public JSAPIRuntimeTest {
    255 public:
    256  virtual ~OperatorFixture() = default;
    257 
    258  template <typename T, typename U, size_t N>
    259  bool testOperator(const std::array<U, N>& values);
    260 };
    261 
    262 template <typename T, typename U, size_t N>
    263 bool OperatorFixture::testOperator(const std::array<U, N>& values) {
    264  // Unary operators.
    265  for (auto x : values) {
    266    // Sign operators.
    267    CHECK_EQUAL(U(+T{x}), +x);
    268    CHECK_EQUAL(U(-T{x}), -x);
    269 
    270    // Bitwise operators.
    271    CHECK_EQUAL(U(~T{x}), ~x);
    272 
    273    // Increment/Decrement operators.
    274    auto y = T{x};
    275    CHECK_EQUAL(U(++y), x + 1);
    276    CHECK_EQUAL(U(y), x + 1);
    277 
    278    y = T{x};
    279    CHECK_EQUAL(U(y++), x);
    280    CHECK_EQUAL(U(y), x + 1);
    281 
    282    y = T{x};
    283    CHECK_EQUAL(U(--y), x - 1);
    284    CHECK_EQUAL(U(y), x - 1);
    285 
    286    y = T{x};
    287    CHECK_EQUAL(U(y--), x);
    288    CHECK_EQUAL(U(y), x - 1);
    289  }
    290 
    291  // Binary operators.
    292  for (auto x : values) {
    293    for (auto y : values) {
    294      // Comparison operators.
    295      CHECK_EQUAL((T{x} == T{y}), (x == y));
    296      CHECK_EQUAL((T{x} != T{y}), (x != y));
    297      CHECK_EQUAL((T{x} < T{y}), (x < y));
    298      CHECK_EQUAL((T{x} <= T{y}), (x <= y));
    299      CHECK_EQUAL((T{x} > T{y}), (x > y));
    300      CHECK_EQUAL((T{x} >= T{y}), (x >= y));
    301 
    302      // Add/Sub/Mul operators.
    303      CHECK_EQUAL(U(T{x} + T{y}), (x + y));
    304      CHECK_EQUAL(U(T{x} - T{y}), (x - y));
    305      CHECK_EQUAL(U(T{x} * T{y}), (x * y));
    306 
    307      // Division operators.
    308      if (y != 0) {
    309        CHECK_EQUAL(U(T{x} / T{y}), (x / y));
    310        CHECK_EQUAL(U(T{x} % T{y}), (x % y));
    311      }
    312 
    313      // Shift operators.
    314      if (y >= 0) {
    315        CHECK_EQUAL(U(T{x} << y), (x << y));
    316        CHECK_EQUAL(U(T{x} >> y), (x >> y));
    317      }
    318 
    319      // Bitwise operators.
    320      CHECK_EQUAL(U(T{x} & T{y}), (x & y));
    321      CHECK_EQUAL(U(T{x} | T{y}), (x | y));
    322      CHECK_EQUAL(U(T{x} ^ T{y}), (x ^ y));
    323    }
    324  }
    325 
    326  // Compound assignment operators.
    327  for (auto x : values) {
    328    for (auto y : values) {
    329      auto z = T{x};
    330      z += T{y};
    331      CHECK_EQUAL(U(z), x + y);
    332 
    333      z = T{x};
    334      z -= T{y};
    335      CHECK_EQUAL(U(z), x - y);
    336 
    337      z = T{x};
    338      z *= T{y};
    339      CHECK_EQUAL(U(z), x * y);
    340 
    341      if (y != 0) {
    342        z = T{x};
    343        z /= T{y};
    344        CHECK_EQUAL(U(z), x / y);
    345 
    346        z = T{x};
    347        z %= T{y};
    348        CHECK_EQUAL(U(z), x % y);
    349      }
    350 
    351      if (y >= 0) {
    352        z = T{x};
    353        z <<= y;
    354        CHECK_EQUAL(U(z), x << y);
    355 
    356        z = T{x};
    357        z >>= y;
    358        CHECK_EQUAL(U(z), x >> y);
    359      }
    360 
    361      z = T{x};
    362      z &= T{y};
    363      CHECK_EQUAL(U(z), x & y);
    364 
    365      z = T{x};
    366      z |= T{y};
    367      CHECK_EQUAL(U(z), x | y);
    368 
    369      z = T{x};
    370      z ^= T{y};
    371      CHECK_EQUAL(U(z), x ^ y);
    372    }
    373  }
    374  return true;
    375 }
    376 
    377 BEGIN_FIXTURE_TEST(OperatorFixture, testInt128_operator) {
    378  auto values = std::array{
    379      int64_t(-3), int64_t(-2), int64_t(-1), int64_t(0),
    380      int64_t(1),  int64_t(2),  int64_t(3),  int64_t(63),
    381  };
    382 
    383  CHECK(testOperator<Int128>(values));
    384 
    385  // Values larger than INT64_MAX.
    386  CHECK((Int128{INT64_MAX} * Int128{2}) ==
    387        (Int128{INT64_MAX} + Int128{INT64_MAX}));
    388  CHECK((Int128{INT64_MAX} * Int128{3}) ==
    389        (Int128{INT64_MAX} * Int128{4} - Int128{INT64_MAX}));
    390  CHECK((Int128{INT64_MAX} * Int128{2}) == (Int128{INT64_MAX} << 1));
    391  CHECK((Int128{INT64_MAX} * Int128{8}) == (Int128{INT64_MAX} << 3));
    392  CHECK((Int128{INT64_MAX} * Int128{8} / Int128{2}) ==
    393        (Int128{INT64_MAX} << 2));
    394  CHECK((Int128{INT64_MAX} * Int128{23} % Int128{13}) == (Int128{5}));
    395 
    396  // Values smaller than INT64_MIN.
    397  CHECK((Int128{INT64_MIN} * Int128{2}) ==
    398        (Int128{INT64_MIN} + Int128{INT64_MIN}));
    399  CHECK((Int128{INT64_MIN} * Int128{3}) ==
    400        (Int128{INT64_MIN} * Int128{4} - Int128{INT64_MIN}));
    401  CHECK((Int128{INT64_MIN} * Int128{2}) == (Int128{INT64_MIN} << 1));
    402  CHECK((Int128{INT64_MIN} * Int128{8}) == (Int128{INT64_MIN} << 3));
    403  CHECK((Int128{INT64_MIN} * Int128{8} / Int128{2}) ==
    404        (Int128{INT64_MIN} << 2));
    405  CHECK((Int128{INT64_MIN} * Int128{23} % Int128{13}) == (Int128{-2}));
    406 
    407  return true;
    408 }
    409 END_FIXTURE_TEST(OperatorFixture, testInt128_operator)
    410 
    411 BEGIN_FIXTURE_TEST(OperatorFixture, testUint128_operator) {
    412  auto values = std::array{
    413      uint64_t(0), uint64_t(1), uint64_t(2),
    414      uint64_t(3), uint64_t(5), uint64_t(63),
    415  };
    416 
    417  CHECK(testOperator<Uint128>(values));
    418 
    419  // Values larger than UINT64_MAX.
    420  CHECK((Uint128{UINT64_MAX} * Uint128{2}) ==
    421        (Uint128{UINT64_MAX} + Uint128{UINT64_MAX}));
    422  CHECK((Uint128{UINT64_MAX} * Uint128{3}) ==
    423        (Uint128{UINT64_MAX} * Uint128{4} - Uint128{UINT64_MAX}));
    424  CHECK((Uint128{UINT64_MAX} * Uint128{2}) == (Uint128{UINT64_MAX} << 1));
    425  CHECK((Uint128{UINT64_MAX} * Uint128{8}) == (Uint128{UINT64_MAX} << 3));
    426  CHECK((Uint128{UINT64_MAX} * Uint128{8} / Uint128{2}) ==
    427        (Uint128{UINT64_MAX} << 2));
    428  CHECK((Uint128{UINT64_MAX} * Uint128{23} % Uint128{13}) == (Uint128{7}));
    429 
    430  return true;
    431 }
    432 END_FIXTURE_TEST(OperatorFixture, testUint128_operator)
    433 
    434 BEGIN_TEST(testInt128_literal) {
    435  CHECK_EQUAL(int64_t(0x7fff'ffff'ffff'ffff_i128), INT64_MAX);
    436  CHECK_EQUAL(int64_t(-0x8000'0000'0000'0000_i128), INT64_MIN);
    437 
    438  CHECK(std::numeric_limits<Int128>::max() ==
    439        0x7fff'ffff'ffff'ffff'ffff'ffff'ffff'ffff_i128);
    440  CHECK(std::numeric_limits<Int128>::min() ==
    441        -0x8000'0000'0000'0000'0000'0000'0000'0000_i128);
    442 
    443  auto x = (Int128{INT64_MAX} + Int128{1}) * Int128{3};
    444  CHECK(x == 27670116110564327424_i128);
    445  CHECK(x == 0x1'8000'0000'0000'0000_i128);
    446 
    447  auto y = Int128{0} - (Int128{5} * Int128{INT64_MAX});
    448  CHECK(y == -46116860184273879035_i128);
    449  CHECK(y == -0x2'7fff'ffff'ffff'fffb_i128);
    450 
    451  // NB: This shift expression overflows.
    452  auto z = Int128{0x1122'3344} << 100;
    453  CHECK(z == 0x1223'3440'0000'0000'0000'0000'0000'0000_i128);
    454  CHECK(z == 0221063210000000000000000000000000000000000_i128);
    455  CHECK(z == 24108894070078995479046745700448600064_i128);
    456  CHECK(
    457      z ==
    458      0b10010001000110011010001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_i128);
    459 
    460  z >>= 80;
    461  CHECK(z == 0X1223'3440'0000_i128);
    462  CHECK(z == 0442146420000000_i128);
    463  CHECK(z == 19942409764864_i128);
    464  CHECK(z == 0B100100010001100110100010000000000000000000000_i128);
    465 
    466  auto v = Int128{INT64_MAX} * Int128{INT64_MAX};
    467  CHECK(v == 0x3fff'ffff'ffff'ffff'0000'0000'0000'0001_i128);
    468  CHECK((v + v) == 0x7fff'ffff'ffff'fffe'0000'0000'0000'0002_i128);
    469  CHECK((v * v) == 0x7fff'ffff'ffff'fffe'0000'0000'0000'0001_i128);
    470  CHECK((v * -v) == -0x7fff'ffff'ffff'fffe'0000'0000'0000'0001_i128);
    471  CHECK((-v * v) == -0x7fff'ffff'ffff'fffe'0000'0000'0000'0001_i128);
    472  CHECK((-v * -v) == 0x7fff'ffff'ffff'fffe'0000'0000'0000'0001_i128);
    473 
    474  auto w = Int128{INT64_MIN} * Int128{INT64_MIN};
    475  CHECK(w == 0x4000'0000'0000'0000'0000'0000'0000'0000_i128);
    476  CHECK((w + w) == -0x8000'0000'0000'0000'0000'0000'0000'0000_i128);
    477  CHECK((w * w) == 0_i128);
    478 
    479  CHECK((Int128{1} << 120) == 0x100'0000'0000'0000'0000'0000'0000'0000_i128);
    480 
    481  return true;
    482 }
    483 END_TEST(testInt128_literal)
    484 
    485 BEGIN_TEST(testUint128_literal) {
    486  CHECK_EQUAL(uint64_t(0xffff'ffff'ffff'ffff_u128), UINT64_MAX);
    487 
    488  CHECK(std::numeric_limits<Uint128>::max() ==
    489        0xffff'ffff'ffff'ffff'ffff'ffff'ffff'ffff_u128);
    490 
    491  auto x = (Uint128{UINT64_MAX} + Uint128{3}) * Uint128{3};
    492  CHECK(x == 55340232221128654854_u128);
    493  CHECK(x == 0x3'0000'0000'0000'0006_u128);
    494 
    495  // NB: This shift expression overflows.
    496  auto z = Uint128{0x1122'3344} << 100;
    497  CHECK(z == 0x1223'3440'0000'0000'0000'0000'0000'0000_u128);
    498  CHECK(z == 0221063210000000000000000000000000000000000_u128);
    499  CHECK(z == 24108894070078995479046745700448600064_u128);
    500  CHECK(
    501      z ==
    502      0b10010001000110011010001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128);
    503 
    504  z >>= 80;
    505  CHECK(z == 0X1223'3440'0000_u128);
    506  CHECK(z == 0442146420000000_u128);
    507  CHECK(z == 19942409764864_u128);
    508  CHECK(z == 0B100100010001100110100010000000000000000000000_u128);
    509 
    510  auto v = Uint128{UINT64_MAX} * Uint128{UINT64_MAX};
    511  CHECK(v == 0xffff'ffff'ffff'fffe'0000'0000'0000'0001_u128);
    512  CHECK((v + v) == 0xffff'ffff'ffff'fffc'0000'0000'0000'0002_u128);
    513  CHECK((v * v) == 0xffff'ffff'ffff'fffc'0000'0000'0000'0001_u128);
    514  CHECK((v * -v) == 0x3'ffff'ffff'ffff'ffff_u128);
    515  CHECK((-v * v) == 0x3'ffff'ffff'ffff'ffff_u128);
    516  CHECK((-v * -v) == 0xffff'ffff'ffff'fffc'0000'0000'0000'0001_u128);
    517 
    518  CHECK((Uint128{1} << 120) == 0x100'0000'0000'0000'0000'0000'0000'0000_u128);
    519 
    520  return true;
    521 }
    522 END_TEST(testUint128_literal)
    523 
    524 BEGIN_TEST(testInt128_division) {
    525  auto x = Int128{INT64_MAX} * Int128{4};
    526  CHECK((x / Int128{2}) == 0xffff'ffff'ffff'fffe_i128);
    527  CHECK((x / Int128{2}) == (x >> 1));
    528 
    529  auto y = Int128{INT64_MAX} * Int128{16};
    530  CHECK((y / Int128{2}) == 0x3'ffff'ffff'ffff'fff8_i128);
    531  CHECK((y / Int128{2}) == (y >> 1));
    532 
    533  CHECK((0x1122'3344'5566'7788'aabb'ccdd'ff12'3456_i128 / 7_i128) ==
    534        0x272'999c'0c33'35a5'cf3f'6668'db4b'be55_i128);
    535  CHECK((0x1122'3344'5566'7788'aabb'ccdd'ff12'3456_i128 /
    536         0x1'2345'6789'abcd'ef11'abcd'ef11_i128) == 0xf0f0f0f_i128);
    537  CHECK((7_i128 / 0x1122'3344'5566'7788'aabb'ccdd'ff12'3456_i128) == 0_i128);
    538 
    539  CHECK((0x1122'3344'5566'7788'aabb'ccdd'ff12'3456_i128 % 7_i128) == 3_i128);
    540  CHECK((0x1122'3344'5566'7788'aabb'ccdd'ff12'3456_i128 %
    541         0x1'2345'6789'abcd'ef11'abcd'ef11_i128) ==
    542        0x1122'3353'7d8e'9fb0'dc00'3357_i128);
    543  CHECK((7_i128 % 0x1122'3344'5566'7788'aabb'ccdd'ff12'3456_i128) == 7_i128);
    544 
    545  return true;
    546 }
    547 END_TEST(testInt128_division)
    548 
    549 BEGIN_TEST(testInt128_abs) {
    550  CHECK((0_i128).abs() == 0_u128);
    551 
    552  CHECK((0x1122'3344_i128).abs() == 0x1122'3344_u128);
    553  CHECK((-0x1122'3344_i128).abs() == 0x1122'3344_u128);
    554 
    555  CHECK((0x1111'2222'3333'4444'5555'6666'7777'8888_i128).abs() ==
    556        0x1111'2222'3333'4444'5555'6666'7777'8888_u128);
    557  CHECK((-0x1111'2222'3333'4444'5555'6666'7777'8888_i128).abs() ==
    558        0x1111'2222'3333'4444'5555'6666'7777'8888_u128);
    559 
    560  CHECK(std::numeric_limits<Int128>::min().abs() ==
    561        0x8000'0000'0000'0000'0000'0000'0000'0000_u128);
    562  CHECK(std::numeric_limits<Int128>::max().abs() ==
    563        0x7fff'ffff'ffff'ffff'ffff'ffff'ffff'ffff_u128);
    564 
    565  return true;
    566 }
    567 END_TEST(testInt128_abs)
    568 
    569 #endif