brintos

brintos / llvm-project-archived public Read only

0
0
Text · 36.4 KiB · 93a66d5 Raw
1079 lines · cpp
1//===-- Unittests for the UInt integer class ------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/__support/CPP/optional.h"10#include "src/__support/big_int.h"11#include "src/__support/integer_literals.h" // parse_unsigned_bigint12#include "src/__support/macros/config.h"13#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT12814 15#include "hdr/math_macros.h" // HUGE_VALF, HUGE_VALF16#include "test/UnitTest/Test.h"17 18namespace LIBC_NAMESPACE_DECL {19 20enum Value { ZERO, ONE, TWO, MIN, MAX };21 22template <typename T> auto create(Value value) {23  switch (value) {24  case ZERO:25    return T(0);26  case ONE:27    return T(1);28  case TWO:29    return T(2);30  case MIN:31    return T::min();32  case MAX:33    return T::max();34  }35  __builtin_unreachable();36}37 38using Types = testing::TypeList< //39#ifdef LIBC_TYPES_HAS_INT6440    BigInt<64, false, uint64_t>, // 64-bits unsigned (1 x uint64_t)41    BigInt<64, true, uint64_t>,  // 64-bits   signed (1 x uint64_t)42#endif43#ifdef LIBC_TYPES_HAS_INT12844    BigInt<128, false, __uint128_t>, // 128-bits unsigned (1 x __uint128_t)45    BigInt<128, true, __uint128_t>,  // 128-bits   signed (1 x __uint128_t)46#endif47    BigInt<16, false, uint16_t>, // 16-bits unsigned (1 x uint16_t)48    BigInt<16, true, uint16_t>,  // 16-bits   signed (1 x uint16_t)49    BigInt<64, false, uint16_t>, // 64-bits unsigned (4 x uint16_t)50    BigInt<64, true, uint16_t>   // 64-bits   signed (4 x uint16_t)51    >;52 53#define ASSERT_SAME(A, B) ASSERT_TRUE((A) == (B))54 55TYPED_TEST(LlvmLibcUIntClassTest, Additions, Types) {56  ASSERT_SAME(create<T>(ZERO) + create<T>(ZERO), create<T>(ZERO));57  ASSERT_SAME(create<T>(ONE) + create<T>(ZERO), create<T>(ONE));58  ASSERT_SAME(create<T>(ZERO) + create<T>(ONE), create<T>(ONE));59  ASSERT_SAME(create<T>(ONE) + create<T>(ONE), create<T>(TWO));60  // 2's complement addition works for signed and unsigned types.61  // - unsigned : 0xff + 0x01 = 0x00 (255 + 1 = 0)62  // -   signed : 0xef + 0x01 = 0xf0 (127 + 1 = -128)63  ASSERT_SAME(create<T>(MAX) + create<T>(ONE), create<T>(MIN));64}65 66TYPED_TEST(LlvmLibcUIntClassTest, Subtraction, Types) {67  ASSERT_SAME(create<T>(ZERO) - create<T>(ZERO), create<T>(ZERO));68  ASSERT_SAME(create<T>(ONE) - create<T>(ONE), create<T>(ZERO));69  ASSERT_SAME(create<T>(ONE) - create<T>(ZERO), create<T>(ONE));70  // 2's complement subtraction works for signed and unsigned types.71  // - unsigned : 0x00 - 0x01 = 0xff (   0 - 1 = 255)72  // -   signed : 0xf0 - 0x01 = 0xef (-128 - 1 = 127)73  ASSERT_SAME(create<T>(MIN) - create<T>(ONE), create<T>(MAX));74}75 76TYPED_TEST(LlvmLibcUIntClassTest, Multiplication, Types) {77  ASSERT_SAME(create<T>(ZERO) * create<T>(ZERO), create<T>(ZERO));78  ASSERT_SAME(create<T>(ZERO) * create<T>(ONE), create<T>(ZERO));79  ASSERT_SAME(create<T>(ONE) * create<T>(ZERO), create<T>(ZERO));80  ASSERT_SAME(create<T>(ONE) * create<T>(ONE), create<T>(ONE));81  ASSERT_SAME(create<T>(ONE) * create<T>(TWO), create<T>(TWO));82  ASSERT_SAME(create<T>(TWO) * create<T>(ONE), create<T>(TWO));83  // - unsigned : 0xff x 0xff = 0x01 (mod 0xff)84  // -   signed : 0xef x 0xef = 0x01 (mod 0xff)85  ASSERT_SAME(create<T>(MAX) * create<T>(MAX), create<T>(ONE));86}87 88template <typename T> void print(const char *msg, T value) {89  testing::tlog << msg;90  IntegerToString<T, radix::Hex> buffer(value);91  testing::tlog << buffer.view() << "\n";92}93 94TEST(LlvmLibcUIntClassTest, SignedAddSub) {95  // Computations performed by https://www.wolframalpha.com/96  using T = BigInt<128, true, uint32_t>;97  const T a = parse_bigint<T>("1927508279017230597");98  const T b = parse_bigint<T>("278789278723478925");99  const T s = parse_bigint<T>("2206297557740709522");100  // Addition101  ASSERT_SAME(a + b, s);102  ASSERT_SAME(b + a, s); // commutative103  // Subtraction104  ASSERT_SAME(a - s, -b);105  ASSERT_SAME(s - a, b);106}107 108TEST(LlvmLibcUIntClassTest, SignedMulDiv) {109  // Computations performed by https://www.wolframalpha.com/110  using T = BigInt<128, true, uint16_t>;111  struct {112    const char *a;113    const char *b;114    const char *mul;115  } const test_cases[] = {{"-4", "3", "-12"},116                          {"-3", "-3", "9"},117                          {"1927508279017230597", "278789278723478925",118                           "537368642840747885329125014794668225"}};119  for (auto tc : test_cases) {120    const T a = parse_bigint<T>(tc.a);121    const T b = parse_bigint<T>(tc.b);122    const T mul = parse_bigint<T>(tc.mul);123    // Multiplication124    ASSERT_SAME(a * b, mul);125    ASSERT_SAME(b * a, mul);   // commutative126    ASSERT_SAME(a * -b, -mul); // sign127    ASSERT_SAME(-a * b, -mul); // sign128    ASSERT_SAME(-a * -b, mul); // sign129    // Division130    ASSERT_SAME(mul / a, b);131    ASSERT_SAME(mul / b, a);132    ASSERT_SAME(-mul / a, -b); // sign133    ASSERT_SAME(mul / -a, -b); // sign134    ASSERT_SAME(-mul / -a, b); // sign135  }136}137 138TYPED_TEST(LlvmLibcUIntClassTest, Division, Types) {139  ASSERT_SAME(create<T>(ZERO) / create<T>(ONE), create<T>(ZERO));140  ASSERT_SAME(create<T>(MAX) / create<T>(ONE), create<T>(MAX));141  ASSERT_SAME(create<T>(MAX) / create<T>(MAX), create<T>(ONE));142  ASSERT_SAME(create<T>(ONE) / create<T>(ONE), create<T>(ONE));143  if constexpr (T::SIGNED) {144    // Special case found by fuzzing.145    ASSERT_SAME(create<T>(MIN) / create<T>(MIN), create<T>(ONE));146  }147  // - unsigned : 0xff / 0x02 = 0x7f148  // -   signed : 0xef / 0x02 = 0x77149  ASSERT_SAME(create<T>(MAX) / create<T>(TWO), (create<T>(MAX) >> 1));150 151  using word_type = typename T::word_type;152  const T zero_one_repeated = T::all_ones() / T(0xff);153  const word_type pattern = word_type(~0) / word_type(0xff);154  for (const word_type part : zero_one_repeated.val) {155    if constexpr (T::SIGNED == false) {156      EXPECT_EQ(part, pattern);157    }158  }159}160 161TYPED_TEST(LlvmLibcUIntClassTest, is_neg, Types) {162  EXPECT_FALSE(create<T>(ZERO).is_neg());163  EXPECT_FALSE(create<T>(ONE).is_neg());164  EXPECT_FALSE(create<T>(TWO).is_neg());165  EXPECT_EQ(create<T>(MIN).is_neg(), T::SIGNED);166  EXPECT_FALSE(create<T>(MAX).is_neg());167}168 169TYPED_TEST(LlvmLibcUIntClassTest, Masks, Types) {170  if constexpr (!T::SIGNED) {171    constexpr size_t BITS = T::BITS;172    // mask_trailing_ones173    ASSERT_SAME((mask_trailing_ones<T, 0>()), T::zero());174    ASSERT_SAME((mask_trailing_ones<T, 1>()), T::one());175    ASSERT_SAME((mask_trailing_ones<T, BITS - 1>()), T::all_ones() >> 1);176    ASSERT_SAME((mask_trailing_ones<T, BITS>()), T::all_ones());177    // mask_leading_ones178    ASSERT_SAME((mask_leading_ones<T, 0>()), T::zero());179    ASSERT_SAME((mask_leading_ones<T, 1>()), T::one() << (BITS - 1));180    ASSERT_SAME((mask_leading_ones<T, BITS - 1>()), T::all_ones() - T::one());181    ASSERT_SAME((mask_leading_ones<T, BITS>()), T::all_ones());182    // mask_trailing_zeros183    ASSERT_SAME((mask_trailing_zeros<T, 0>()), T::all_ones());184    ASSERT_SAME((mask_trailing_zeros<T, 1>()), T::all_ones() - T::one());185    ASSERT_SAME((mask_trailing_zeros<T, BITS - 1>()), T::one() << (BITS - 1));186    ASSERT_SAME((mask_trailing_zeros<T, BITS>()), T::zero());187    // mask_trailing_zeros188    ASSERT_SAME((mask_leading_zeros<T, 0>()), T::all_ones());189    ASSERT_SAME((mask_leading_zeros<T, 1>()), T::all_ones() >> 1);190    ASSERT_SAME((mask_leading_zeros<T, BITS - 1>()), T::one());191    ASSERT_SAME((mask_leading_zeros<T, BITS>()), T::zero());192  }193}194 195TYPED_TEST(LlvmLibcUIntClassTest, CountBits, Types) {196  if constexpr (!T::SIGNED) {197    for (size_t i = 0; i < T::BITS; ++i) {198      const auto l_one = T::all_ones() << i; // 0b111...000199      const auto r_one = T::all_ones() >> i; // 0b000...111200      const int zeros = static_cast<int>(i);201      const int ones = static_cast<int>(T::BITS - static_cast<size_t>(zeros));202      ASSERT_EQ(cpp::countr_one(r_one), ones);203      ASSERT_EQ(cpp::countl_one(l_one), ones);204      ASSERT_EQ(cpp::countr_zero(l_one), zeros);205      ASSERT_EQ(cpp::countl_zero(r_one), zeros);206    }207  }208}209 210using LL_UInt16 = UInt<16>;211using LL_UInt32 = UInt<32>;212using LL_UInt64 = UInt<64>;213// We want to test UInt<128> explicitly. So, for214// convenience, we use a sugar which does not conflict with the UInt128 type215// which can resolve to __uint128_t if the platform has it.216using LL_UInt128 = UInt<128>;217using LL_UInt192 = UInt<192>;218using LL_UInt256 = UInt<256>;219using LL_UInt320 = UInt<320>;220using LL_UInt512 = UInt<512>;221using LL_UInt1024 = UInt<1024>;222 223using LL_Int128 = Int<128>;224using LL_Int192 = Int<192>;225 226TEST(LlvmLibcUIntClassTest, BitCastToFromDouble) {227  static_assert(cpp::is_trivially_copyable<LL_UInt64>::value);228  static_assert(sizeof(LL_UInt64) == sizeof(double));229  const double inf = HUGE_VAL;230  const double max = DBL_MAX;231  const double array[] = {0.0, 0.1, 1.0, max, inf};232  for (double value : array) {233    LL_UInt64 back = cpp::bit_cast<LL_UInt64>(value);234    double forth = cpp::bit_cast<double>(back);235    EXPECT_TRUE(value == forth);236  }237}238 239#ifdef LIBC_TYPES_HAS_INT128240TEST(LlvmLibcUIntClassTest, BitCastToFromNativeUint128) {241  static_assert(cpp::is_trivially_copyable<LL_UInt128>::value);242  static_assert(sizeof(LL_UInt128) == sizeof(__uint128_t));243  const __uint128_t array[] = {0, 1, ~__uint128_t(0)};244  for (__uint128_t value : array) {245    LL_UInt128 back = cpp::bit_cast<LL_UInt128>(value);246    __uint128_t forth = cpp::bit_cast<__uint128_t>(back);247    EXPECT_TRUE(value == forth);248  }249}250#endif // LIBC_TYPES_HAS_INT128251 252#ifdef LIBC_TYPES_HAS_FLOAT128253TEST(LlvmLibcUIntClassTest, BitCastToFromNativeFloat128) {254  static_assert(cpp::is_trivially_copyable<LL_UInt128>::value);255  static_assert(sizeof(LL_UInt128) == sizeof(float128));256  const float128 array[] = {0, 0.1, 1};257  for (float128 value : array) {258    LL_UInt128 back = cpp::bit_cast<LL_UInt128>(value);259    float128 forth = cpp::bit_cast<float128>(back);260    EXPECT_TRUE(value == forth);261  }262}263#endif // LIBC_TYPES_HAS_FLOAT128264 265#ifdef LIBC_TYPES_HAS_FLOAT16266TEST(LlvmLibcUIntClassTest, BitCastToFromNativeFloat16) {267  static_assert(cpp::is_trivially_copyable<LL_UInt16>::value);268  static_assert(sizeof(LL_UInt16) == sizeof(float16));269  const float16 array[] = {270      static_cast<float16>(0.0),271      static_cast<float16>(0.1),272      static_cast<float16>(1.0),273  };274  for (float16 value : array) {275    LL_UInt16 back = cpp::bit_cast<LL_UInt16>(value);276    float16 forth = cpp::bit_cast<float16>(back);277    EXPECT_TRUE(value == forth);278  }279}280#endif // LIBC_TYPES_HAS_FLOAT16281 282TEST(LlvmLibcUIntClassTest, BasicInit) {283  LL_UInt128 half_val(12345);284  LL_UInt128 full_val({12345, 67890});285  ASSERT_TRUE(half_val != full_val);286}287 288TEST(LlvmLibcUIntClassTest, AdditionTests) {289  LL_UInt128 val1(12345);290  LL_UInt128 val2(54321);291  LL_UInt128 result1(66666);292  EXPECT_EQ(val1 + val2, result1);293  EXPECT_EQ((val1 + val2), (val2 + val1)); // addition is commutative294 295  // Test overflow296  LL_UInt128 val3({0xf000000000000001, 0});297  LL_UInt128 val4({0x100000000000000f, 0});298  LL_UInt128 result2({0x10, 0x1});299  EXPECT_EQ(val3 + val4, result2);300  EXPECT_EQ(val3 + val4, val4 + val3);301 302  // Test overflow303  LL_UInt128 val5({0x0123456789abcdef, 0xfedcba9876543210});304  LL_UInt128 val6({0x1111222233334444, 0xaaaabbbbccccdddd});305  LL_UInt128 result3({0x12346789bcdf1233, 0xa987765443210fed});306  EXPECT_EQ(val5 + val6, result3);307  EXPECT_EQ(val5 + val6, val6 + val5);308 309  // Test 192-bit addition310  LL_UInt192 val7({0x0123456789abcdef, 0xfedcba9876543210, 0xfedcba9889abcdef});311  LL_UInt192 val8({0x1111222233334444, 0xaaaabbbbccccdddd, 0xeeeeffffeeeeffff});312  LL_UInt192 result4(313      {0x12346789bcdf1233, 0xa987765443210fed, 0xedcbba98789acdef});314  EXPECT_EQ(val7 + val8, result4);315  EXPECT_EQ(val7 + val8, val8 + val7);316 317  // Test 256-bit addition318  LL_UInt256 val9({0x1f1e1d1c1b1a1918, 0xf1f2f3f4f5f6f7f8, 0x0123456789abcdef,319                   0xfedcba9876543210});320  LL_UInt256 val10({0x1111222233334444, 0xaaaabbbbccccdddd, 0x1111222233334444,321                    0xaaaabbbbccccdddd});322  LL_UInt256 result5({0x302f3f3e4e4d5d5c, 0x9c9dafb0c2c3d5d5,323                      0x12346789bcdf1234, 0xa987765443210fed});324  EXPECT_EQ(val9 + val10, result5);325  EXPECT_EQ(val9 + val10, val10 + val9);326}327 328TEST(LlvmLibcUIntClassTest, SubtractionTests) {329  LL_UInt128 val1(12345);330  LL_UInt128 val2(54321);331  LL_UInt128 result1({0xffffffffffff5c08, 0xffffffffffffffff});332  LL_UInt128 result2(0xa3f8);333  EXPECT_EQ(val1 - val2, result1);334  EXPECT_EQ(val1, val2 + result1);335  EXPECT_EQ(val2 - val1, result2);336  EXPECT_EQ(val2, val1 + result2);337 338  LL_UInt128 val3({0xf000000000000001, 0});339  LL_UInt128 val4({0x100000000000000f, 0});340  LL_UInt128 result3(0xdffffffffffffff2);341  LL_UInt128 result4({0x200000000000000e, 0xffffffffffffffff});342  EXPECT_EQ(val3 - val4, result3);343  EXPECT_EQ(val3, val4 + result3);344  EXPECT_EQ(val4 - val3, result4);345  EXPECT_EQ(val4, val3 + result4);346 347  LL_UInt128 val5({0x0123456789abcdef, 0xfedcba9876543210});348  LL_UInt128 val6({0x1111222233334444, 0xaaaabbbbccccdddd});349  LL_UInt128 result5({0xf0122345567889ab, 0x5431fedca9875432});350  LL_UInt128 result6({0x0feddcbaa9877655, 0xabce01235678abcd});351  EXPECT_EQ(val5 - val6, result5);352  EXPECT_EQ(val5, val6 + result5);353  EXPECT_EQ(val6 - val5, result6);354  EXPECT_EQ(val6, val5 + result6);355}356 357TEST(LlvmLibcUIntClassTest, MultiplicationTests) {358  LL_UInt128 val1({5, 0});359  LL_UInt128 val2({10, 0});360  LL_UInt128 result1({50, 0});361  EXPECT_EQ((val1 * val2), result1);362  EXPECT_EQ((val1 * val2), (val2 * val1)); // multiplication is commutative363 364  // Check that the multiplication works accross the whole number365  LL_UInt128 val3({0xf, 0});366  LL_UInt128 val4({0x1111111111111111, 0x1111111111111111});367  LL_UInt128 result2({0xffffffffffffffff, 0xffffffffffffffff});368  EXPECT_EQ((val3 * val4), result2);369  EXPECT_EQ((val3 * val4), (val4 * val3));370 371  // Check that multiplication doesn't reorder the bits.372  LL_UInt128 val5({2, 0});373  LL_UInt128 val6({0x1357024675316420, 0x0123456776543210});374  LL_UInt128 result3({0x26ae048cea62c840, 0x02468aceeca86420});375 376  EXPECT_EQ((val5 * val6), result3);377  EXPECT_EQ((val5 * val6), (val6 * val5));378 379  // Make sure that multiplication handles overflow correctly.380  LL_UInt128 val7(2);381  LL_UInt128 val8({0x8000800080008000, 0x8000800080008000});382  LL_UInt128 result4({0x0001000100010000, 0x0001000100010001});383  EXPECT_EQ((val7 * val8), result4);384  EXPECT_EQ((val7 * val8), (val8 * val7));385 386  // val9 is the 128 bit mantissa of 1e60 as a float, val10 is the mantissa for387  // 1e-60. They almost cancel on the high bits, but the result we're looking388  // for is just the low bits. The full result would be389  // 0x7fffffffffffffffffffffffffffffff3a4f32d17f40d08f917cf11d1e039c50390  LL_UInt128 val9({0x01D762422C946590, 0x9F4F2726179A2245});391  LL_UInt128 val10({0x3792F412CB06794D, 0xCDB02555653131B6});392  LL_UInt128 result5({0x917cf11d1e039c50, 0x3a4f32d17f40d08f});393  EXPECT_EQ((val9 * val10), result5);394  EXPECT_EQ((val9 * val10), (val10 * val9));395 396  // Test 192-bit multiplication397  LL_UInt192 val11(398      {0xffffffffffffffff, 0x01D762422C946590, 0x9F4F2726179A2245});399  LL_UInt192 val12(400      {0xffffffffffffffff, 0x3792F412CB06794D, 0xCDB02555653131B6});401 402  LL_UInt192 result6(403      {0x0000000000000001, 0xc695a9ab08652121, 0x5de7faf698d32732});404  EXPECT_EQ((val11 * val12), result6);405  EXPECT_EQ((val11 * val12), (val12 * val11));406 407  LL_UInt256 val13({0xffffffffffffffff, 0x01D762422C946590, 0x9F4F2726179A2245,408                    0xffffffffffffffff});409  LL_UInt256 val14({0xffffffffffffffff, 0xffffffffffffffff, 0x3792F412CB06794D,410                    0xCDB02555653131B6});411  LL_UInt256 result7({0x0000000000000001, 0xfe289dbdd36b9a6f,412                      0x291de4c71d5f646c, 0xfd37221cb06d4978});413  EXPECT_EQ((val13 * val14), result7);414  EXPECT_EQ((val13 * val14), (val14 * val13));415}416 417TEST(LlvmLibcUIntClassTest, DivisionTests) {418  LL_UInt128 val1({10, 0});419  LL_UInt128 val2({5, 0});420  LL_UInt128 result1({2, 0});421  EXPECT_EQ((val1 / val2), result1);422  EXPECT_EQ((val1 / result1), val2);423 424  // Check that the division works accross the whole number425  LL_UInt128 val3({0xffffffffffffffff, 0xffffffffffffffff});426  LL_UInt128 val4({0xf, 0});427  LL_UInt128 result2({0x1111111111111111, 0x1111111111111111});428  EXPECT_EQ((val3 / val4), result2);429  EXPECT_EQ((val3 / result2), val4);430 431  // Check that division doesn't reorder the bits.432  LL_UInt128 val5({0x26ae048cea62c840, 0x02468aceeca86420});433  LL_UInt128 val6({2, 0});434  LL_UInt128 result3({0x1357024675316420, 0x0123456776543210});435  EXPECT_EQ((val5 / val6), result3);436  EXPECT_EQ((val5 / result3), val6);437 438  // Make sure that division handles inexact results correctly.439  LL_UInt128 val7({1001, 0});440  LL_UInt128 val8({10, 0});441  LL_UInt128 result4({100, 0});442  EXPECT_EQ((val7 / val8), result4);443  EXPECT_EQ((val7 / result4), val8);444 445  // Make sure that division handles divisors of one correctly.446  LL_UInt128 val9({0x1234567812345678, 0x9abcdef09abcdef0});447  LL_UInt128 val10({1, 0});448  LL_UInt128 result5({0x1234567812345678, 0x9abcdef09abcdef0});449  EXPECT_EQ((val9 / val10), result5);450  EXPECT_EQ((val9 / result5), val10);451 452  // Make sure that division handles results of slightly more than 1 correctly.453  LL_UInt128 val11({1050, 0});454  LL_UInt128 val12({1030, 0});455  LL_UInt128 result6({1, 0});456  EXPECT_EQ((val11 / val12), result6);457 458  // Make sure that division handles dividing by zero correctly.459  LL_UInt128 val13({1234, 0});460  LL_UInt128 val14({0, 0});461  EXPECT_FALSE(val13.div(val14).has_value());462}463 464TEST(LlvmLibcUIntClassTest, ModuloTests) {465  LL_UInt128 val1({10, 0});466  LL_UInt128 val2({5, 0});467  LL_UInt128 result1({0, 0});468  EXPECT_EQ((val1 % val2), result1);469 470  LL_UInt128 val3({101, 0});471  LL_UInt128 val4({10, 0});472  LL_UInt128 result2({1, 0});473  EXPECT_EQ((val3 % val4), result2);474 475  LL_UInt128 val5({10000001, 0});476  LL_UInt128 val6({10, 0});477  LL_UInt128 result3({1, 0});478  EXPECT_EQ((val5 % val6), result3);479 480  LL_UInt128 val7({12345, 10});481  LL_UInt128 val8({0, 1});482  LL_UInt128 result4({12345, 0});483  EXPECT_EQ((val7 % val8), result4);484 485  LL_UInt128 val9({12345, 10});486  LL_UInt128 val10({0, 11});487  LL_UInt128 result5({12345, 10});488  EXPECT_EQ((val9 % val10), result5);489 490  LL_UInt128 val11({10, 10});491  LL_UInt128 val12({10, 10});492  LL_UInt128 result6({0, 0});493  EXPECT_EQ((val11 % val12), result6);494 495  LL_UInt128 val13({12345, 0});496  LL_UInt128 val14({1, 0});497  LL_UInt128 result7({0, 0});498  EXPECT_EQ((val13 % val14), result7);499 500  LL_UInt128 val15({0xffffffffffffffff, 0xffffffffffffffff});501  LL_UInt128 val16({0x1111111111111111, 0x111111111111111});502  LL_UInt128 result8({0xf, 0});503  EXPECT_EQ((val15 % val16), result8);504 505  LL_UInt128 val17({5076944270305263619, 54210108624}); // (10 ^ 30) + 3506  LL_UInt128 val18({10, 0});507  LL_UInt128 result9({3, 0});508  EXPECT_EQ((val17 % val18), result9);509}510 511TEST(LlvmLibcUIntClassTest, PowerTests) {512  LL_UInt128 val1({10, 0});513  val1.pow_n(30);514  LL_UInt128 result1({5076944270305263616, 54210108624}); // (10 ^ 30)515  EXPECT_EQ(val1, result1);516 517  LL_UInt128 val2({1, 0});518  val2.pow_n(10);519  LL_UInt128 result2({1, 0});520  EXPECT_EQ(val2, result2);521 522  LL_UInt128 val3({0, 0});523  val3.pow_n(10);524  LL_UInt128 result3({0, 0});525  EXPECT_EQ(val3, result3);526 527  LL_UInt128 val4({10, 0});528  val4.pow_n(0);529  LL_UInt128 result4({1, 0});530  EXPECT_EQ(val4, result4);531 532  // Test zero to the zero. Currently it returns 1, since that's the easiest533  // result.534  LL_UInt128 val5({0, 0});535  val5.pow_n(0);536  LL_UInt128 result5({1, 0});537  EXPECT_EQ(val5, result5);538 539  // Test a number that overflows. 100 ^ 20 is larger than 2 ^ 128.540  LL_UInt128 val6({100, 0});541  val6.pow_n(20);542  LL_UInt128 result6({0xb9f5610000000000, 0x6329f1c35ca4bfab});543  EXPECT_EQ(val6, result6);544 545  // Test that both halves of the number are being used.546  LL_UInt128 val7({1, 1});547  val7.pow_n(2);548  LL_UInt128 result7({1, 2});549  EXPECT_EQ(val7, result7);550 551  LL_UInt128 val_pow_two;552  LL_UInt128 result_pow_two;553  for (size_t i = 0; i < 128; ++i) {554    val_pow_two = 2;555    val_pow_two.pow_n(i);556    result_pow_two = 1;557    result_pow_two = result_pow_two << i;558    EXPECT_EQ(val_pow_two, result_pow_two);559  }560}561 562TEST(LlvmLibcUIntClassTest, ShiftLeftTests) {563  LL_UInt128 val1(0x0123456789abcdef);564  LL_UInt128 result1(0x123456789abcdef0);565  EXPECT_EQ((val1 << 4), result1);566 567  LL_UInt128 val2({0x13579bdf02468ace, 0x123456789abcdef0});568  LL_UInt128 result2({0x02468ace00000000, 0x9abcdef013579bdf});569  EXPECT_EQ((val2 << 32), result2);570  LL_UInt128 val22 = val2;571  val22 <<= 32;572  EXPECT_EQ(val22, result2);573 574  LL_UInt128 result3({0, 0x13579bdf02468ace});575  EXPECT_EQ((val2 << 64), result3);576 577  LL_UInt128 result4({0, 0x02468ace00000000});578  EXPECT_EQ((val2 << 96), result4);579 580  LL_UInt128 result5({0, 0x2468ace000000000});581  EXPECT_EQ((val2 << 100), result5);582 583  LL_UInt192 val3({1, 0, 0});584  LL_UInt192 result7({0, 1, 0});585  EXPECT_EQ((val3 << 64), result7);586}587 588TEST(LlvmLibcUIntClassTest, ShiftRightTests) {589  LL_UInt128 val1(0x0123456789abcdef);590  LL_UInt128 result1(0x00123456789abcde);591  EXPECT_EQ((val1 >> 4), result1);592 593  LL_UInt128 val2({0x13579bdf02468ace, 0x123456789abcdef0});594  LL_UInt128 result2({0x9abcdef013579bdf, 0x0000000012345678});595  EXPECT_EQ((val2 >> 32), result2);596  LL_UInt128 val22 = val2;597  val22 >>= 32;598  EXPECT_EQ(val22, result2);599 600  LL_UInt128 result3({0x123456789abcdef0, 0});601  EXPECT_EQ((val2 >> 64), result3);602 603  LL_UInt128 result4({0x0000000012345678, 0});604  EXPECT_EQ((val2 >> 96), result4);605 606  LL_UInt128 result5({0x0000000001234567, 0});607  EXPECT_EQ((val2 >> 100), result5);608 609  LL_UInt128 v1({0x1111222233334444, 0xaaaabbbbccccdddd});610  LL_UInt128 r1({0xaaaabbbbccccdddd, 0});611  EXPECT_EQ((v1 >> 64), r1);612 613  LL_UInt192 v2({0x1111222233334444, 0x5555666677778888, 0xaaaabbbbccccdddd});614  LL_UInt192 r2({0x5555666677778888, 0xaaaabbbbccccdddd, 0});615  LL_UInt192 r3({0xaaaabbbbccccdddd, 0, 0});616  EXPECT_EQ((v2 >> 64), r2);617  EXPECT_EQ((v2 >> 128), r3);618  EXPECT_EQ((r2 >> 64), r3);619 620  LL_UInt192 val3({0, 0, 1});621  LL_UInt192 result7({0, 1, 0});622  EXPECT_EQ((val3 >> 64), result7);623}624 625TEST(LlvmLibcUIntClassTest, AndTests) {626  LL_UInt128 base({0xffff00000000ffff, 0xffffffff00000000});627  LL_UInt128 val128({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});628  uint64_t val64 = 0xf0f0f0f00f0f0f0f;629  int val32 = 0x0f0f0f0f;630  LL_UInt128 result128({0xf0f0000000000f0f, 0xff00ff0000000000});631  LL_UInt128 result64(0xf0f0000000000f0f);632  LL_UInt128 result32(0x00000f0f);633  EXPECT_EQ((base & val128), result128);634  EXPECT_EQ((base & val64), result64);635  EXPECT_EQ((base & val32), result32);636}637 638TEST(LlvmLibcUIntClassTest, OrTests) {639  LL_UInt128 base({0xffff00000000ffff, 0xffffffff00000000});640  LL_UInt128 val128({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});641  uint64_t val64 = 0xf0f0f0f00f0f0f0f;642  int val32 = 0x0f0f0f0f;643  LL_UInt128 result128({0xfffff0f00f0fffff, 0xffffffff00ff00ff});644  LL_UInt128 result64({0xfffff0f00f0fffff, 0xffffffff00000000});645  LL_UInt128 result32({0xffff00000f0fffff, 0xffffffff00000000});646  EXPECT_EQ((base | val128), result128);647  EXPECT_EQ((base | val64), result64);648  EXPECT_EQ((base | val32), result32);649}650 651TEST(LlvmLibcUIntClassTest, CompoundAssignments) {652  LL_UInt128 x({0xffff00000000ffff, 0xffffffff00000000});653  LL_UInt128 b({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});654 655  LL_UInt128 a = x;656  a |= b;657  LL_UInt128 or_result({0xfffff0f00f0fffff, 0xffffffff00ff00ff});658  EXPECT_EQ(a, or_result);659 660  a = x;661  a &= b;662  LL_UInt128 and_result({0xf0f0000000000f0f, 0xff00ff0000000000});663  EXPECT_EQ(a, and_result);664 665  a = x;666  a ^= b;667  LL_UInt128 xor_result({0x0f0ff0f00f0ff0f0, 0x00ff00ff00ff00ff});668  EXPECT_EQ(a, xor_result);669 670  a = LL_UInt128(uint64_t(0x0123456789abcdef));671  LL_UInt128 shift_left_result(uint64_t(0x123456789abcdef0));672  a <<= 4;673  EXPECT_EQ(a, shift_left_result);674 675  a = LL_UInt128(uint64_t(0x123456789abcdef1));676  LL_UInt128 shift_right_result(uint64_t(0x0123456789abcdef));677  a >>= 4;678  EXPECT_EQ(a, shift_right_result);679 680  a = LL_UInt128({0xf000000000000001, 0});681  b = LL_UInt128({0x100000000000000f, 0});682  LL_UInt128 add_result({0x10, 0x1});683  a += b;684  EXPECT_EQ(a, add_result);685 686  a = LL_UInt128({0xf, 0});687  b = LL_UInt128({0x1111111111111111, 0x1111111111111111});688  LL_UInt128 mul_result({0xffffffffffffffff, 0xffffffffffffffff});689  a *= b;690  EXPECT_EQ(a, mul_result);691}692 693TEST(LlvmLibcUIntClassTest, UnaryPredecrement) {694  LL_UInt128 a = LL_UInt128({0x1111111111111111, 0x1111111111111111});695  ++a;696  EXPECT_EQ(a, LL_UInt128({0x1111111111111112, 0x1111111111111111}));697 698  a = LL_UInt128({0xffffffffffffffff, 0x0});699  ++a;700  EXPECT_EQ(a, LL_UInt128({0x0, 0x1}));701 702  a = LL_UInt128({0xffffffffffffffff, 0xffffffffffffffff});703  ++a;704  EXPECT_EQ(a, LL_UInt128({0x0, 0x0}));705}706 707TEST(LlvmLibcUIntClassTest, EqualsTests) {708  LL_UInt128 a1({0xffffffff00000000, 0xffff00000000ffff});709  LL_UInt128 a2({0xffffffff00000000, 0xffff00000000ffff});710  LL_UInt128 b({0xff00ff0000ff00ff, 0xf0f0f0f00f0f0f0f});711  LL_UInt128 a_reversed({0xffff00000000ffff, 0xffffffff00000000});712  LL_UInt128 a_upper(0xffff00000000ffff);713  LL_UInt128 a_lower(0xffffffff00000000);714  ASSERT_TRUE(a1 == a1);715  ASSERT_TRUE(a1 == a2);716  ASSERT_FALSE(a1 == b);717  ASSERT_FALSE(a1 == a_reversed);718  ASSERT_FALSE(a1 == a_lower);719  ASSERT_FALSE(a1 == a_upper);720  ASSERT_TRUE(a_lower != a_upper);721}722 723TEST(LlvmLibcUIntClassTest, ComparisonTests) {724  LL_UInt128 a({0xffffffff00000000, 0xffff00000000ffff});725  LL_UInt128 b({0xff00ff0000ff00ff, 0xf0f0f0f00f0f0f0f});726  EXPECT_GT(a, b);727  EXPECT_GE(a, b);728  EXPECT_LT(b, a);729  EXPECT_LE(b, a);730 731  LL_UInt128 x(0xffffffff00000000);732  LL_UInt128 y(0x00000000ffffffff);733  EXPECT_GT(x, y);734  EXPECT_GE(x, y);735  EXPECT_LT(y, x);736  EXPECT_LE(y, x);737 738  EXPECT_LE(a, a);739  EXPECT_GE(a, a);740}741 742TEST(LlvmLibcUIntClassTest, FullMulTests) {743  LL_UInt128 a({0xffffffffffffffffULL, 0xffffffffffffffffULL});744  LL_UInt128 b({0xfedcba9876543210ULL, 0xfefdfcfbfaf9f8f7ULL});745  LL_UInt256 r({0x0123456789abcdf0ULL, 0x0102030405060708ULL,746                0xfedcba987654320fULL, 0xfefdfcfbfaf9f8f7ULL});747  LL_UInt128 r_hi({0xfedcba987654320eULL, 0xfefdfcfbfaf9f8f7ULL});748 749  EXPECT_EQ(a.ful_mul(b), r);750  EXPECT_EQ(a.quick_mul_hi(b), r_hi);751 752  LL_UInt192 c(753      {0x7766554433221101ULL, 0xffeeddccbbaa9988ULL, 0x1f2f3f4f5f6f7f8fULL});754  LL_UInt320 rr({0x8899aabbccddeeffULL, 0x0011223344556677ULL,755                 0x583715f4d3b29171ULL, 0xffeeddccbbaa9988ULL,756                 0x1f2f3f4f5f6f7f8fULL});757 758  EXPECT_EQ(a.ful_mul(c), rr);759  EXPECT_EQ(a.ful_mul(c), c.ful_mul(a));760}761 762#define TEST_QUICK_MUL_HI(Bits, Error)                                         \763  do {                                                                         \764    LL_UInt##Bits a = ~LL_UInt##Bits(0);                                       \765    LL_UInt##Bits hi = a.quick_mul_hi(a);                                      \766    LL_UInt##Bits trunc = static_cast<LL_UInt##Bits>(a.ful_mul(a) >> Bits);    \767    uint64_t overflow = trunc.sub_overflow(hi);                                \768    EXPECT_EQ(overflow, uint64_t(0));                                          \769    EXPECT_LE(uint64_t(trunc), uint64_t(Error));                               \770  } while (0)771 772TEST(LlvmLibcUIntClassTest, QuickMulHiTests) {773  TEST_QUICK_MUL_HI(128, 1);774  TEST_QUICK_MUL_HI(192, 2);775  TEST_QUICK_MUL_HI(256, 3);776  TEST_QUICK_MUL_HI(512, 7);777}778 779TEST(LlvmLibcUIntClassTest, ConstexprInitTests) {780  constexpr LL_UInt128 add = LL_UInt128(1) + LL_UInt128(2);781  ASSERT_EQ(add, LL_UInt128(3));782  constexpr LL_UInt128 sub = LL_UInt128(5) - LL_UInt128(4);783  ASSERT_EQ(sub, LL_UInt128(1));784}785 786#define TEST_QUICK_DIV_UINT32_POW2(x, e)                                       \787  do {                                                                         \788    LL_UInt320 y({0x8899aabbccddeeffULL, 0x0011223344556677ULL,                \789                  0x583715f4d3b29171ULL, 0xffeeddccbbaa9988ULL,                \790                  0x1f2f3f4f5f6f7f8fULL});                                     \791    LL_UInt320 d = LL_UInt320(x);                                              \792    d <<= e;                                                                   \793    LL_UInt320 q1 = y / d;                                                     \794    LL_UInt320 r1 = y % d;                                                     \795    LL_UInt320 r2 = *y.div_uint_half_times_pow_2(x, e);                        \796    EXPECT_EQ(q1, y);                                                          \797    EXPECT_EQ(r1, r2);                                                         \798  } while (0)799 800TEST(LlvmLibcUIntClassTest, DivUInt32TimesPow2Tests) {801  for (size_t i = 0; i < 320; i += 32) {802    TEST_QUICK_DIV_UINT32_POW2(1, i);803    TEST_QUICK_DIV_UINT32_POW2(13151719, i);804  }805 806  TEST_QUICK_DIV_UINT32_POW2(1, 75);807  TEST_QUICK_DIV_UINT32_POW2(1, 101);808 809  TEST_QUICK_DIV_UINT32_POW2(1000000000, 75);810  TEST_QUICK_DIV_UINT32_POW2(1000000000, 101);811}812 813TEST(LlvmLibcUIntClassTest, ComparisonInt128Tests) {814  LL_Int128 a(123);815  LL_Int128 b(0);816  LL_Int128 c(-1);817 818  ASSERT_TRUE(a == a);819  ASSERT_TRUE(b == b);820  ASSERT_TRUE(c == c);821 822  ASSERT_TRUE(a != b);823  ASSERT_TRUE(a != c);824  ASSERT_TRUE(b != a);825  ASSERT_TRUE(b != c);826  ASSERT_TRUE(c != a);827  ASSERT_TRUE(c != b);828 829  ASSERT_TRUE(a > b);830  ASSERT_TRUE(a >= b);831  ASSERT_TRUE(a > c);832  ASSERT_TRUE(a >= c);833  ASSERT_TRUE(b > c);834  ASSERT_TRUE(b >= c);835 836  ASSERT_TRUE(b < a);837  ASSERT_TRUE(b <= a);838  ASSERT_TRUE(c < a);839  ASSERT_TRUE(c <= a);840  ASSERT_TRUE(c < b);841  ASSERT_TRUE(c <= b);842}843 844TEST(LlvmLibcUIntClassTest, BasicArithmeticInt128Tests) {845  LL_Int128 a(123);846  LL_Int128 b(0);847  LL_Int128 c(-3);848 849  ASSERT_EQ(a * a, LL_Int128(123 * 123));850  ASSERT_EQ(a * c, LL_Int128(-369));851  ASSERT_EQ(c * a, LL_Int128(-369));852  ASSERT_EQ(c * c, LL_Int128(9));853  ASSERT_EQ(a * b, b);854  ASSERT_EQ(b * a, b);855  ASSERT_EQ(b * c, b);856  ASSERT_EQ(c * b, b);857}858 859#ifdef LIBC_TYPES_HAS_INT128860 861TEST(LlvmLibcUIntClassTest, ConstructorFromUInt128Tests) {862  __uint128_t a = (__uint128_t(123) << 64) + 1;863  __int128_t b = -static_cast<__int128_t>(a);864  LL_Int128 c(a);865  LL_Int128 d(b);866 867  LL_Int192 e(a);868  LL_Int192 f(b);869 870  ASSERT_EQ(static_cast<int>(c), 1);871  ASSERT_EQ(static_cast<int>(c >> 64), 123);872  ASSERT_EQ(static_cast<uint64_t>(d), static_cast<uint64_t>(b));873  ASSERT_EQ(static_cast<uint64_t>(d >> 64), static_cast<uint64_t>(b >> 64));874  ASSERT_EQ(c + d, LL_Int128(a + static_cast<__uint128_t>(b)));875 876  ASSERT_EQ(static_cast<int>(e), 1);877  ASSERT_EQ(static_cast<int>(e >> 64), 123);878  ASSERT_EQ(static_cast<uint64_t>(f), static_cast<uint64_t>(b));879  ASSERT_EQ(static_cast<uint64_t>(f >> 64), static_cast<uint64_t>(b >> 64));880  ASSERT_EQ(LL_UInt192(e + f), LL_UInt192(a + static_cast<__uint128_t>(b)));881}882 883TEST(LlvmLibcUIntClassTest, WordTypeUInt128Tests) {884  using LL_UInt256_128 = BigInt<256, false, __uint128_t>;885  using LL_UInt128_128 = BigInt<128, false, __uint128_t>;886 887  LL_UInt256_128 a(1);888 889  ASSERT_EQ(static_cast<int>(a), 1);890  a = (a << 128) + 2;891  ASSERT_EQ(static_cast<int>(a), 2);892  ASSERT_EQ(static_cast<uint64_t>(a), uint64_t(2));893  a = (a << 32) + 3;894  ASSERT_EQ(static_cast<int>(a), 3);895  ASSERT_EQ(static_cast<uint64_t>(a), uint64_t(0x2'0000'0003));896  ASSERT_EQ(static_cast<int>(a >> 32), 2);897  ASSERT_EQ(static_cast<int>(a >> (128 + 32)), 1);898 899  LL_UInt128_128 b(__uint128_t(1) << 127);900  LL_UInt128_128 c(b);901  a = b.ful_mul(c);902 903  ASSERT_EQ(static_cast<int>(a >> 254), 1);904 905  LL_UInt256_128 d = LL_UInt256_128(123) << 4;906  ASSERT_EQ(static_cast<int>(d), 123 << 4);907  LL_UInt256_128 e = a / d;908  LL_UInt256_128 f = a % d;909  LL_UInt256_128 r = *a.div_uint_half_times_pow_2(123, 4);910  EXPECT_TRUE(e == a);911  EXPECT_TRUE(f == r);912}913 914#endif // LIBC_TYPES_HAS_INT128915 916TEST(LlvmLibcUIntClassTest, OtherWordTypeTests) {917  using LL_UInt96 = BigInt<96, false, uint32_t>;918 919  LL_UInt96 a(1);920 921  ASSERT_EQ(static_cast<int>(a), 1);922  a = (a << 32) + 2;923  ASSERT_EQ(static_cast<int>(a), 2);924  ASSERT_EQ(static_cast<uint64_t>(a), uint64_t(0x1'0000'0002));925  a = (a << 32) + 3;926  ASSERT_EQ(static_cast<int>(a), 3);927  ASSERT_EQ(static_cast<int>(a >> 32), 2);928  ASSERT_EQ(static_cast<int>(a >> 64), 1);929}930 931TEST(LlvmLibcUIntClassTest, OtherWordTypeCastTests) {932  using LL_UInt96 = BigInt<96, false, uint32_t>;933 934  LL_UInt96 a({123, 456, 789});935 936  ASSERT_EQ(static_cast<int>(a), 123);937  ASSERT_EQ(static_cast<int>(a >> 32), 456);938  ASSERT_EQ(static_cast<int>(a >> 64), 789);939 940  // Bigger word with more bits to smaller word with less bits.941  LL_UInt128 b(a);942 943  ASSERT_EQ(static_cast<int>(b), 123);944  ASSERT_EQ(static_cast<int>(b >> 32), 456);945  ASSERT_EQ(static_cast<int>(b >> 64), 789);946  ASSERT_EQ(static_cast<int>(b >> 96), 0);947 948  b = (b << 32) + 987;949 950  ASSERT_EQ(static_cast<int>(b), 987);951  ASSERT_EQ(static_cast<int>(b >> 32), 123);952  ASSERT_EQ(static_cast<int>(b >> 64), 456);953  ASSERT_EQ(static_cast<int>(b >> 96), 789);954 955  // Smaller word with less bits to bigger word with more bits.956  LL_UInt96 c(b);957 958  ASSERT_EQ(static_cast<int>(c), 987);959  ASSERT_EQ(static_cast<int>(c >> 32), 123);960  ASSERT_EQ(static_cast<int>(c >> 64), 456);961 962  // Smaller word with more bits to bigger word with less bits963  LL_UInt64 d(c);964 965  ASSERT_EQ(static_cast<int>(d), 987);966  ASSERT_EQ(static_cast<int>(d >> 32), 123);967 968  // Bigger word with less bits to smaller word with more bits969 970  LL_UInt96 e(d);971 972  ASSERT_EQ(static_cast<int>(e), 987);973  ASSERT_EQ(static_cast<int>(e >> 32), 123);974 975  e = (e << 32) + 654;976 977  ASSERT_EQ(static_cast<int>(e), 654);978  ASSERT_EQ(static_cast<int>(e >> 32), 987);979  ASSERT_EQ(static_cast<int>(e >> 64), 123);980}981 982TEST(LlvmLibcUIntClassTest, SignedOtherWordTypeCastTests) {983  using LL_Int64 = BigInt<64, true, uint64_t>;984  using LL_Int96 = BigInt<96, true, uint32_t>;985 986  LL_Int64 zero_64(0);987  LL_Int96 zero_96(0);988  LL_Int192 zero_192(0);989 990  LL_Int96 plus_a({0x1234, 0x5678, 0x9ABC});991 992  ASSERT_EQ(static_cast<int>(plus_a), 0x1234);993  ASSERT_EQ(static_cast<int>(plus_a >> 32), 0x5678);994  ASSERT_EQ(static_cast<int>(plus_a >> 64), 0x9ABC);995 996  LL_Int96 minus_a(-plus_a);997 998  // The reason that the numbers are inverted and not negated is that we're999  // using two's complement. To negate a two's complement number you flip the1000  // bits and add 1, so minus_a is {~0x1234, ~0x5678, ~0x9ABC} + {1,0,0}.1001  ASSERT_EQ(static_cast<int>(minus_a), (~0x1234) + 1);1002  ASSERT_EQ(static_cast<int>(minus_a >> 32), ~0x5678);1003  ASSERT_EQ(static_cast<int>(minus_a >> 64), ~0x9ABC);1004 1005  ASSERT_TRUE(plus_a + minus_a == zero_96);1006 1007  // 192 so there's an extra block to get sign extended to1008  LL_Int192 bigger_plus_a(plus_a);1009 1010  ASSERT_EQ(static_cast<int>(bigger_plus_a), 0x1234);1011  ASSERT_EQ(static_cast<int>(bigger_plus_a >> 32), 0x5678);1012  ASSERT_EQ(static_cast<int>(bigger_plus_a >> 64), 0x9ABC);1013  ASSERT_EQ(static_cast<int>(bigger_plus_a >> 96), 0);1014  ASSERT_EQ(static_cast<int>(bigger_plus_a >> 128), 0);1015  ASSERT_EQ(static_cast<int>(bigger_plus_a >> 160), 0);1016 1017  LL_Int192 bigger_minus_a(minus_a);1018 1019  ASSERT_EQ(static_cast<int>(bigger_minus_a), (~0x1234) + 1);1020  ASSERT_EQ(static_cast<int>(bigger_minus_a >> 32), ~0x5678);1021  ASSERT_EQ(static_cast<int>(bigger_minus_a >> 64), ~0x9ABC);1022  ASSERT_EQ(static_cast<int>(bigger_minus_a >> 96), ~0);1023  ASSERT_EQ(static_cast<int>(bigger_minus_a >> 128), ~0);1024  ASSERT_EQ(static_cast<int>(bigger_minus_a >> 160), ~0);1025 1026  ASSERT_TRUE(bigger_plus_a + bigger_minus_a == zero_192);1027 1028  LL_Int64 smaller_plus_a(plus_a);1029 1030  ASSERT_EQ(static_cast<int>(smaller_plus_a), 0x1234);1031  ASSERT_EQ(static_cast<int>(smaller_plus_a >> 32), 0x5678);1032 1033  LL_Int64 smaller_minus_a(minus_a);1034 1035  ASSERT_EQ(static_cast<int>(smaller_minus_a), (~0x1234) + 1);1036  ASSERT_EQ(static_cast<int>(smaller_minus_a >> 32), ~0x5678);1037 1038  ASSERT_TRUE(smaller_plus_a + smaller_minus_a == zero_64);1039 1040  // Also try going from bigger word size to smaller word size1041  LL_Int96 smaller_back_plus_a(smaller_plus_a);1042 1043  ASSERT_EQ(static_cast<int>(smaller_back_plus_a), 0x1234);1044  ASSERT_EQ(static_cast<int>(smaller_back_plus_a >> 32), 0x5678);1045  ASSERT_EQ(static_cast<int>(smaller_back_plus_a >> 64), 0);1046 1047  LL_Int96 smaller_back_minus_a(smaller_minus_a);1048 1049  ASSERT_EQ(static_cast<int>(smaller_back_minus_a), (~0x1234) + 1);1050  ASSERT_EQ(static_cast<int>(smaller_back_minus_a >> 32), ~0x5678);1051  ASSERT_EQ(static_cast<int>(smaller_back_minus_a >> 64), ~0);1052 1053  ASSERT_TRUE(smaller_back_plus_a + smaller_back_minus_a == zero_96);1054 1055  LL_Int96 bigger_back_plus_a(bigger_plus_a);1056 1057  ASSERT_EQ(static_cast<int>(bigger_back_plus_a), 0x1234);1058  ASSERT_EQ(static_cast<int>(bigger_back_plus_a >> 32), 0x5678);1059  ASSERT_EQ(static_cast<int>(bigger_back_plus_a >> 64), 0x9ABC);1060 1061  LL_Int96 bigger_back_minus_a(bigger_minus_a);1062 1063  ASSERT_EQ(static_cast<int>(bigger_back_minus_a), (~0x1234) + 1);1064  ASSERT_EQ(static_cast<int>(bigger_back_minus_a >> 32), ~0x5678);1065  ASSERT_EQ(static_cast<int>(bigger_back_minus_a >> 64), ~0x9ABC);1066 1067  ASSERT_TRUE(bigger_back_plus_a + bigger_back_minus_a == zero_96);1068}1069 1070TEST(LlvmLibcUIntClassTest, MixedSignednessOtherWordTypeCastTests) {1071  using LL_UInt96 = BigInt<96, false, uint32_t>;1072  LL_UInt96 x = -123;1073  // ensure that -123 gets extended, even though the input type is signed while1074  // the BigInt is unsigned.1075  ASSERT_EQ(int64_t(x), int64_t(-123));1076}1077 1078} // namespace LIBC_NAMESPACE_DECL1079