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-exception 6 // 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_bigint 12 #include "src/__support/macros/config.h" 13 #include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128 14 15 #include "hdr/math_macros.h" // HUGE_VALF, HUGE_VALF 16 #include "test/UnitTest/Test.h" 17 18 namespace LIBC_NAMESPACE_DECL { 19 20 enum Value { ZERO, ONE, TWO, MIN, MAX }; 21 22 template <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 38 using Types = testing::TypeList< // 39 #ifdef LIBC_TYPES_HAS_INT64 40 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 #endif 43 #ifdef LIBC_TYPES_HAS_INT128 44 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 #endif 47 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 55 TYPED_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 66 TYPED_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 76 TYPED_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 88 template <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 94 TEST(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 // Addition 101 ASSERT_SAME(a + b, s); 102 ASSERT_SAME(b + a, s); // commutative 103 // Subtraction 104 ASSERT_SAME(a - s, -b); 105 ASSERT_SAME(s - a, b); 106 } 107 108 TEST(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 // Multiplication 124 ASSERT_SAME(a * b, mul); 125 ASSERT_SAME(b * a, mul); // commutative 126 ASSERT_SAME(a * -b, -mul); // sign 127 ASSERT_SAME(-a * b, -mul); // sign 128 ASSERT_SAME(-a * -b, mul); // sign 129 // Division 130 ASSERT_SAME(mul / a, b); 131 ASSERT_SAME(mul / b, a); 132 ASSERT_SAME(-mul / a, -b); // sign 133 ASSERT_SAME(mul / -a, -b); // sign 134 ASSERT_SAME(-mul / -a, b); // sign 135 } 136 } 137 138 TYPED_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 = 0x7f 148 // - signed : 0xef / 0x02 = 0x77 149 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 161 TYPED_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 169 TYPED_TEST(LlvmLibcUIntClassTest, Masks, Types) { 170 if constexpr (!T::SIGNED) { 171 constexpr size_t BITS = T::BITS; 172 // mask_trailing_ones 173 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_ones 178 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_zeros 183 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_zeros 188 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 195 TYPED_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...000 199 const auto r_one = T::all_ones() >> i; // 0b000...111 200 const int zeros = i; 201 const int ones = T::BITS - 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 210 using LL_UInt16 = UInt<16>; 211 using LL_UInt32 = UInt<32>; 212 using LL_UInt64 = UInt<64>; 213 // We want to test UInt<128> explicitly. So, for 214 // convenience, we use a sugar which does not conflict with the UInt128 type 215 // which can resolve to __uint128_t if the platform has it. 216 using LL_UInt128 = UInt<128>; 217 using LL_UInt192 = UInt<192>; 218 using LL_UInt256 = UInt<256>; 219 using LL_UInt320 = UInt<320>; 220 using LL_UInt512 = UInt<512>; 221 using LL_UInt1024 = UInt<1024>; 222 223 using LL_Int128 = Int<128>; 224 using LL_Int192 = Int<192>; 225 226 TEST(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_INT128 240 TEST(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_INT128 251 252 #ifdef LIBC_TYPES_HAS_FLOAT128 253 TEST(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_FLOAT128 264 265 #ifdef LIBC_TYPES_HAS_FLOAT16 266 TEST(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_FLOAT16 281 282 TEST(LlvmLibcUIntClassTest, BasicInit) { 283 LL_UInt128 half_val(12345); 284 LL_UInt128 full_val({12345, 67890}); 285 ASSERT_TRUE(half_val != full_val); 286 } 287 288 TEST(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 commutative 294 295 // Test overflow 296 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 overflow 303 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 addition 310 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 addition 318 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 328 TEST(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 357 TEST(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 commutative 363 364 // Check that the multiplication works accross the whole number 365 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 for 387 // 1e-60. They almost cancel on the high bits, but the result we're looking 388 // for is just the low bits. The full result would be 389 // 0x7fffffffffffffffffffffffffffffff3a4f32d17f40d08f917cf11d1e039c50 390 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 multiplication 397 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 417 TEST(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 number 425 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 464 TEST(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) + 3 506 LL_UInt128 val18({10, 0}); 507 LL_UInt128 result9({3, 0}); 508 EXPECT_EQ((val17 % val18), result9); 509 } 510 511 TEST(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 easiest 533 // 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 562 TEST(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 588 TEST(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 625 TEST(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 638 TEST(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 651 TEST(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 693 TEST(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 707 TEST(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 723 TEST(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 742 TEST(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 772 TEST(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 779 TEST(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 800 TEST(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 813 TEST(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 844 TEST(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_INT128 860 861 TEST(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 + 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 + b)); 881 } 882 883 TEST(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_INT128 915 916 TEST(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 931 TEST(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 bits 963 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 bits 969 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 982 TEST(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're 999 // using two's complement. To negate a two's complement number you flip the 1000 // 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 to 1008 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 size 1041 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 1070 TEST(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 while 1074 // the BigInt is unsigned. 1075 ASSERT_EQ(int64_t(x), int64_t(-123)); 1076 } 1077 1078 } // namespace LIBC_NAMESPACE_DECL 1079