11170951cSMichael Jones //===-- Unittests for the 128 bit integer class ---------------------------===//
21170951cSMichael Jones //
31170951cSMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41170951cSMichael Jones // See https://llvm.org/LICENSE.txt for license information.
51170951cSMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61170951cSMichael Jones //
71170951cSMichael Jones //===----------------------------------------------------------------------===//
81170951cSMichael Jones 
91170951cSMichael Jones #include "src/__support/CPP/UInt.h"
101170951cSMichael Jones 
111170951cSMichael Jones #include "utils/UnitTest/Test.h"
121170951cSMichael Jones 
13300f8da8SSiva Chandra Reddy // We want to test __llvm_libc::cpp::UInt<128> explicitly. So, for convenience,
14300f8da8SSiva Chandra Reddy // we use a sugar which does not conflict with the UInt128 type which can
15300f8da8SSiva Chandra Reddy // resolve to __uint128_t if the platform has it.
16300f8da8SSiva Chandra Reddy using LL_UInt128 = __llvm_libc::cpp::UInt<128>;
171170951cSMichael Jones 
TEST(LlvmLibcUInt128ClassTest,BasicInit)181170951cSMichael Jones TEST(LlvmLibcUInt128ClassTest, BasicInit) {
19300f8da8SSiva Chandra Reddy   LL_UInt128 empty;
20300f8da8SSiva Chandra Reddy   LL_UInt128 half_val(12345);
21300f8da8SSiva Chandra Reddy   LL_UInt128 full_val({12345, 67890});
221170951cSMichael Jones   ASSERT_TRUE(half_val != full_val);
231170951cSMichael Jones }
241170951cSMichael Jones 
TEST(LlvmLibcUInt128ClassTest,AdditionTests)251170951cSMichael Jones TEST(LlvmLibcUInt128ClassTest, AdditionTests) {
26300f8da8SSiva Chandra Reddy   LL_UInt128 val1(12345);
27300f8da8SSiva Chandra Reddy   LL_UInt128 val2(54321);
28300f8da8SSiva Chandra Reddy   LL_UInt128 result1(66666);
291170951cSMichael Jones   EXPECT_EQ(val1 + val2, result1);
301170951cSMichael Jones   EXPECT_EQ((val1 + val2), (val2 + val1)); // addition is reciprocal
311170951cSMichael Jones 
321170951cSMichael Jones   // Test overflow
33300f8da8SSiva Chandra Reddy   LL_UInt128 val3({0xf000000000000001, 0});
34300f8da8SSiva Chandra Reddy   LL_UInt128 val4({0x100000000000000f, 0});
35300f8da8SSiva Chandra Reddy   LL_UInt128 result2({0x10, 0x1});
361170951cSMichael Jones   EXPECT_EQ(val3 + val4, result2);
371170951cSMichael Jones   EXPECT_EQ(val3 + val4, val4 + val3);
381170951cSMichael Jones }
391170951cSMichael Jones 
TEST(LlvmLibcUInt128ClassTest,MultiplicationTests)401170951cSMichael Jones TEST(LlvmLibcUInt128ClassTest, MultiplicationTests) {
41300f8da8SSiva Chandra Reddy   LL_UInt128 val1({5, 0});
42300f8da8SSiva Chandra Reddy   LL_UInt128 val2({10, 0});
43300f8da8SSiva Chandra Reddy   LL_UInt128 result1({50, 0});
441170951cSMichael Jones   EXPECT_EQ((val1 * val2), result1);
451170951cSMichael Jones   EXPECT_EQ((val1 * val2), (val2 * val1)); // multiplication is reciprocal
461170951cSMichael Jones 
471170951cSMichael Jones   // Check that the multiplication works accross the whole number
48300f8da8SSiva Chandra Reddy   LL_UInt128 val3({0xf, 0});
49300f8da8SSiva Chandra Reddy   LL_UInt128 val4({0x1111111111111111, 0x1111111111111111});
50300f8da8SSiva Chandra Reddy   LL_UInt128 result2({0xffffffffffffffff, 0xffffffffffffffff});
511170951cSMichael Jones   EXPECT_EQ((val3 * val4), result2);
521170951cSMichael Jones   EXPECT_EQ((val3 * val4), (val4 * val3));
531170951cSMichael Jones 
541170951cSMichael Jones   // Check that multiplication doesn't reorder the bits.
55300f8da8SSiva Chandra Reddy   LL_UInt128 val5({2, 0});
56300f8da8SSiva Chandra Reddy   LL_UInt128 val6({0x1357024675316420, 0x0123456776543210});
57300f8da8SSiva Chandra Reddy   LL_UInt128 result3({0x26ae048cea62c840, 0x02468aceeca86420});
581170951cSMichael Jones 
591170951cSMichael Jones   EXPECT_EQ((val5 * val6), result3);
601170951cSMichael Jones   EXPECT_EQ((val5 * val6), (val6 * val5));
611170951cSMichael Jones 
621170951cSMichael Jones   // Make sure that multiplication handles overflow correctly.
63300f8da8SSiva Chandra Reddy   LL_UInt128 val7(2);
64300f8da8SSiva Chandra Reddy   LL_UInt128 val8({0x8000800080008000, 0x8000800080008000});
65300f8da8SSiva Chandra Reddy   LL_UInt128 result4({0x0001000100010000, 0x0001000100010001});
661170951cSMichael Jones   EXPECT_EQ((val7 * val8), result4);
671170951cSMichael Jones   EXPECT_EQ((val7 * val8), (val8 * val7));
681170951cSMichael Jones 
691170951cSMichael Jones   // val9 is the 128 bit mantissa of 1e60 as a float, val10 is the mantissa for
701170951cSMichael Jones   // 1e-60. They almost cancel on the high bits, but the result we're looking
711170951cSMichael Jones   // for is just the low bits. The full result would be
721170951cSMichael Jones   // 0x7fffffffffffffffffffffffffffffff3a4f32d17f40d08f917cf11d1e039c50
73300f8da8SSiva Chandra Reddy   LL_UInt128 val9({0x01D762422C946590, 0x9F4F2726179A2245});
74300f8da8SSiva Chandra Reddy   LL_UInt128 val10({0x3792F412CB06794D, 0xCDB02555653131B6});
75300f8da8SSiva Chandra Reddy   LL_UInt128 result5({0x917cf11d1e039c50, 0x3a4f32d17f40d08f});
761170951cSMichael Jones   EXPECT_EQ((val9 * val10), result5);
771170951cSMichael Jones   EXPECT_EQ((val9 * val10), (val10 * val9));
781170951cSMichael Jones }
791170951cSMichael Jones 
TEST(LlvmLibcUInt128ClassTest,ShiftLeftTests)801170951cSMichael Jones TEST(LlvmLibcUInt128ClassTest, ShiftLeftTests) {
81300f8da8SSiva Chandra Reddy   LL_UInt128 val1(0x0123456789abcdef);
82300f8da8SSiva Chandra Reddy   LL_UInt128 result1(0x123456789abcdef0);
831170951cSMichael Jones   EXPECT_EQ((val1 << 4), result1);
841170951cSMichael Jones 
85300f8da8SSiva Chandra Reddy   LL_UInt128 val2({0x13579bdf02468ace, 0x123456789abcdef0});
86300f8da8SSiva Chandra Reddy   LL_UInt128 result2({0x02468ace00000000, 0x9abcdef013579bdf});
871170951cSMichael Jones   EXPECT_EQ((val2 << 32), result2);
88300f8da8SSiva Chandra Reddy   LL_UInt128 val22 = val2;
89300f8da8SSiva Chandra Reddy   val22 <<= 32;
90300f8da8SSiva Chandra Reddy   EXPECT_EQ(val22, result2);
911170951cSMichael Jones 
92300f8da8SSiva Chandra Reddy   LL_UInt128 result3({0, 0x13579bdf02468ace});
931170951cSMichael Jones   EXPECT_EQ((val2 << 64), result3);
941170951cSMichael Jones 
95300f8da8SSiva Chandra Reddy   LL_UInt128 result4({0, 0x02468ace00000000});
961170951cSMichael Jones   EXPECT_EQ((val2 << 96), result4);
971170951cSMichael Jones 
98300f8da8SSiva Chandra Reddy   LL_UInt128 result5({0, 0x2468ace000000000});
991170951cSMichael Jones   EXPECT_EQ((val2 << 100), result5);
1001170951cSMichael Jones 
101300f8da8SSiva Chandra Reddy   LL_UInt128 result6({0, 0});
1021170951cSMichael Jones   EXPECT_EQ((val2 << 128), result6);
1031170951cSMichael Jones   EXPECT_EQ((val2 << 256), result6);
1041170951cSMichael Jones }
1051170951cSMichael Jones 
TEST(LlvmLibcUInt128ClassTest,ShiftRightTests)1061170951cSMichael Jones TEST(LlvmLibcUInt128ClassTest, ShiftRightTests) {
107300f8da8SSiva Chandra Reddy   LL_UInt128 val1(0x0123456789abcdef);
108300f8da8SSiva Chandra Reddy   LL_UInt128 result1(0x00123456789abcde);
1091170951cSMichael Jones   EXPECT_EQ((val1 >> 4), result1);
1101170951cSMichael Jones 
111300f8da8SSiva Chandra Reddy   LL_UInt128 val2({0x13579bdf02468ace, 0x123456789abcdef0});
112300f8da8SSiva Chandra Reddy   LL_UInt128 result2({0x9abcdef013579bdf, 0x0000000012345678});
1131170951cSMichael Jones   EXPECT_EQ((val2 >> 32), result2);
114300f8da8SSiva Chandra Reddy   LL_UInt128 val22 = val2;
115300f8da8SSiva Chandra Reddy   val22 >>= 32;
116300f8da8SSiva Chandra Reddy   EXPECT_EQ(val22, result2);
1171170951cSMichael Jones 
118300f8da8SSiva Chandra Reddy   LL_UInt128 result3({0x123456789abcdef0, 0});
1191170951cSMichael Jones   EXPECT_EQ((val2 >> 64), result3);
1201170951cSMichael Jones 
121300f8da8SSiva Chandra Reddy   LL_UInt128 result4({0x0000000012345678, 0});
1221170951cSMichael Jones   EXPECT_EQ((val2 >> 96), result4);
1231170951cSMichael Jones 
124300f8da8SSiva Chandra Reddy   LL_UInt128 result5({0x0000000001234567, 0});
1251170951cSMichael Jones   EXPECT_EQ((val2 >> 100), result5);
1261170951cSMichael Jones 
127300f8da8SSiva Chandra Reddy   LL_UInt128 result6({0, 0});
1281170951cSMichael Jones   EXPECT_EQ((val2 >> 128), result6);
1291170951cSMichael Jones   EXPECT_EQ((val2 >> 256), result6);
1301170951cSMichael Jones }
1311170951cSMichael Jones 
TEST(LlvmLibcUInt128ClassTest,AndTests)1321170951cSMichael Jones TEST(LlvmLibcUInt128ClassTest, AndTests) {
133300f8da8SSiva Chandra Reddy   LL_UInt128 base({0xffff00000000ffff, 0xffffffff00000000});
134300f8da8SSiva Chandra Reddy   LL_UInt128 val128({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
1351170951cSMichael Jones   uint64_t val64 = 0xf0f0f0f00f0f0f0f;
1361170951cSMichael Jones   int val32 = 0x0f0f0f0f;
137300f8da8SSiva Chandra Reddy   LL_UInt128 result128({0xf0f0000000000f0f, 0xff00ff0000000000});
138300f8da8SSiva Chandra Reddy   LL_UInt128 result64(0xf0f0000000000f0f);
139300f8da8SSiva Chandra Reddy   LL_UInt128 result32(0x00000f0f);
1401170951cSMichael Jones   EXPECT_EQ((base & val128), result128);
1411170951cSMichael Jones   EXPECT_EQ((base & val64), result64);
1421170951cSMichael Jones   EXPECT_EQ((base & val32), result32);
1431170951cSMichael Jones }
1441170951cSMichael Jones 
TEST(LlvmLibcUInt128ClassTest,OrTests)1451170951cSMichael Jones TEST(LlvmLibcUInt128ClassTest, OrTests) {
146300f8da8SSiva Chandra Reddy   LL_UInt128 base({0xffff00000000ffff, 0xffffffff00000000});
147300f8da8SSiva Chandra Reddy   LL_UInt128 val128({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
1481170951cSMichael Jones   uint64_t val64 = 0xf0f0f0f00f0f0f0f;
1491170951cSMichael Jones   int val32 = 0x0f0f0f0f;
150300f8da8SSiva Chandra Reddy   LL_UInt128 result128({0xfffff0f00f0fffff, 0xffffffff00ff00ff});
151300f8da8SSiva Chandra Reddy   LL_UInt128 result64({0xfffff0f00f0fffff, 0xffffffff00000000});
152300f8da8SSiva Chandra Reddy   LL_UInt128 result32({0xffff00000f0fffff, 0xffffffff00000000});
1531170951cSMichael Jones   EXPECT_EQ((base | val128), result128);
1541170951cSMichael Jones   EXPECT_EQ((base | val64), result64);
1551170951cSMichael Jones   EXPECT_EQ((base | val32), result32);
1561170951cSMichael Jones }
1571170951cSMichael Jones 
TEST(LlvmLibcUInt128ClassTest,CompoundAssignments)158*4965cea2SSiva Chandra Reddy TEST(LlvmLibcUInt128ClassTest, CompoundAssignments) {
159*4965cea2SSiva Chandra Reddy   LL_UInt128 x({0xffff00000000ffff, 0xffffffff00000000});
160*4965cea2SSiva Chandra Reddy   LL_UInt128 b({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
161*4965cea2SSiva Chandra Reddy 
162*4965cea2SSiva Chandra Reddy   LL_UInt128 a = x;
163*4965cea2SSiva Chandra Reddy   a |= b;
164*4965cea2SSiva Chandra Reddy   LL_UInt128 or_result({0xfffff0f00f0fffff, 0xffffffff00ff00ff});
165*4965cea2SSiva Chandra Reddy   EXPECT_EQ(a, or_result);
166*4965cea2SSiva Chandra Reddy 
167*4965cea2SSiva Chandra Reddy   a = x;
168*4965cea2SSiva Chandra Reddy   a &= b;
169*4965cea2SSiva Chandra Reddy   LL_UInt128 and_result({0xf0f0000000000f0f, 0xff00ff0000000000});
170*4965cea2SSiva Chandra Reddy   EXPECT_EQ(a, and_result);
171*4965cea2SSiva Chandra Reddy 
172*4965cea2SSiva Chandra Reddy   a = x;
173*4965cea2SSiva Chandra Reddy   a ^= b;
174*4965cea2SSiva Chandra Reddy   LL_UInt128 xor_result({0x0f0ff0f00f0ff0f0, 0x00ff00ff00ff00ff});
175*4965cea2SSiva Chandra Reddy   EXPECT_EQ(a, xor_result);
176*4965cea2SSiva Chandra Reddy 
177*4965cea2SSiva Chandra Reddy   a = LL_UInt128(uint64_t(0x0123456789abcdef));
178*4965cea2SSiva Chandra Reddy   LL_UInt128 shift_left_result(uint64_t(0x123456789abcdef0));
179*4965cea2SSiva Chandra Reddy   a <<= 4;
180*4965cea2SSiva Chandra Reddy   EXPECT_EQ(a, shift_left_result);
181*4965cea2SSiva Chandra Reddy 
182*4965cea2SSiva Chandra Reddy   a = LL_UInt128(uint64_t(0x123456789abcdef1));
183*4965cea2SSiva Chandra Reddy   LL_UInt128 shift_right_result(uint64_t(0x0123456789abcdef));
184*4965cea2SSiva Chandra Reddy   a >>= 4;
185*4965cea2SSiva Chandra Reddy   EXPECT_EQ(a, shift_right_result);
186*4965cea2SSiva Chandra Reddy 
187*4965cea2SSiva Chandra Reddy   a = LL_UInt128({0xf000000000000001, 0});
188*4965cea2SSiva Chandra Reddy   b = LL_UInt128({0x100000000000000f, 0});
189*4965cea2SSiva Chandra Reddy   LL_UInt128 add_result({0x10, 0x1});
190*4965cea2SSiva Chandra Reddy   a += b;
191*4965cea2SSiva Chandra Reddy   EXPECT_EQ(a, add_result);
192*4965cea2SSiva Chandra Reddy 
193*4965cea2SSiva Chandra Reddy   a = LL_UInt128({0xf, 0});
194*4965cea2SSiva Chandra Reddy   b = LL_UInt128({0x1111111111111111, 0x1111111111111111});
195*4965cea2SSiva Chandra Reddy   LL_UInt128 mul_result({0xffffffffffffffff, 0xffffffffffffffff});
196*4965cea2SSiva Chandra Reddy   a *= b;
197*4965cea2SSiva Chandra Reddy   EXPECT_EQ(a, mul_result);
198*4965cea2SSiva Chandra Reddy }
199*4965cea2SSiva Chandra Reddy 
TEST(LlvmLibcUInt128ClassTest,UnaryPredecrement)200*4965cea2SSiva Chandra Reddy TEST(LlvmLibcUInt128ClassTest, UnaryPredecrement) {
201*4965cea2SSiva Chandra Reddy   LL_UInt128 a = LL_UInt128({0x1111111111111111, 0x1111111111111111});
202*4965cea2SSiva Chandra Reddy   ++a;
203*4965cea2SSiva Chandra Reddy   EXPECT_EQ(a, LL_UInt128({0x1111111111111112, 0x1111111111111111}));
204*4965cea2SSiva Chandra Reddy 
205*4965cea2SSiva Chandra Reddy   a = LL_UInt128({0xffffffffffffffff, 0x0});
206*4965cea2SSiva Chandra Reddy   ++a;
207*4965cea2SSiva Chandra Reddy   EXPECT_EQ(a, LL_UInt128({0x0, 0x1}));
208*4965cea2SSiva Chandra Reddy 
209*4965cea2SSiva Chandra Reddy   a = LL_UInt128({0xffffffffffffffff, 0xffffffffffffffff});
210*4965cea2SSiva Chandra Reddy   ++a;
211*4965cea2SSiva Chandra Reddy   EXPECT_EQ(a, LL_UInt128({0x0, 0x0}));
212*4965cea2SSiva Chandra Reddy }
213*4965cea2SSiva Chandra Reddy 
TEST(LlvmLibcUInt128ClassTest,EqualsTests)2141170951cSMichael Jones TEST(LlvmLibcUInt128ClassTest, EqualsTests) {
215300f8da8SSiva Chandra Reddy   LL_UInt128 a1({0xffffffff00000000, 0xffff00000000ffff});
216300f8da8SSiva Chandra Reddy   LL_UInt128 a2({0xffffffff00000000, 0xffff00000000ffff});
217300f8da8SSiva Chandra Reddy   LL_UInt128 b({0xff00ff0000ff00ff, 0xf0f0f0f00f0f0f0f});
218300f8da8SSiva Chandra Reddy   LL_UInt128 a_reversed({0xffff00000000ffff, 0xffffffff00000000});
219300f8da8SSiva Chandra Reddy   LL_UInt128 a_upper(0xffff00000000ffff);
220300f8da8SSiva Chandra Reddy   LL_UInt128 a_lower(0xffffffff00000000);
2211170951cSMichael Jones   ASSERT_TRUE(a1 == a1);
2221170951cSMichael Jones   ASSERT_TRUE(a1 == a2);
2231170951cSMichael Jones   ASSERT_FALSE(a1 == b);
2241170951cSMichael Jones   ASSERT_FALSE(a1 == a_reversed);
2251170951cSMichael Jones   ASSERT_FALSE(a1 == a_lower);
2261170951cSMichael Jones   ASSERT_FALSE(a1 == a_upper);
2271170951cSMichael Jones   ASSERT_TRUE(a_lower != a_upper);
2281170951cSMichael Jones }
2295aa9efbaSSiva Chandra Reddy 
TEST(LlvmLibcUInt128ClassTest,ComparisonTests)2305aa9efbaSSiva Chandra Reddy TEST(LlvmLibcUInt128ClassTest, ComparisonTests) {
231300f8da8SSiva Chandra Reddy   LL_UInt128 a({0xffffffff00000000, 0xffff00000000ffff});
232300f8da8SSiva Chandra Reddy   LL_UInt128 b({0xff00ff0000ff00ff, 0xf0f0f0f00f0f0f0f});
2335aa9efbaSSiva Chandra Reddy   EXPECT_GT(a, b);
2345aa9efbaSSiva Chandra Reddy   EXPECT_GE(a, b);
2355aa9efbaSSiva Chandra Reddy   EXPECT_LT(b, a);
2365aa9efbaSSiva Chandra Reddy   EXPECT_LE(b, a);
2375aa9efbaSSiva Chandra Reddy 
238300f8da8SSiva Chandra Reddy   LL_UInt128 x(0xffffffff00000000);
239300f8da8SSiva Chandra Reddy   LL_UInt128 y(0x00000000ffffffff);
2405aa9efbaSSiva Chandra Reddy   EXPECT_GT(x, y);
2415aa9efbaSSiva Chandra Reddy   EXPECT_GE(x, y);
2425aa9efbaSSiva Chandra Reddy   EXPECT_LT(y, x);
2435aa9efbaSSiva Chandra Reddy   EXPECT_LE(y, x);
2445aa9efbaSSiva Chandra Reddy 
2455aa9efbaSSiva Chandra Reddy   EXPECT_LE(a, a);
2465aa9efbaSSiva Chandra Reddy   EXPECT_GE(a, a);
2475aa9efbaSSiva Chandra Reddy }
248