166d00febSPaula Toth //===-- Unittests for memory_utils ----------------------------------------===// 285314e9bSGuillaume Chatelet // 385314e9bSGuillaume Chatelet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 485314e9bSGuillaume Chatelet // See https://llvm.org/LICENSE.txt for license information. 585314e9bSGuillaume Chatelet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 685314e9bSGuillaume Chatelet // 785314e9bSGuillaume Chatelet //===----------------------------------------------------------------------===// 885314e9bSGuillaume Chatelet 9d3d498fbSGuillaume Chatelet #include "src/__support/CPP/array.h" 10*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 1185314e9bSGuillaume Chatelet #include "src/string/memory_utils/utils.h" 12af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h" 1385314e9bSGuillaume Chatelet 14*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 1585314e9bSGuillaume Chatelet 16a786096fSGuillaume Chatelet using UINT = uintptr_t; 1785314e9bSGuillaume Chatelet 1885314e9bSGuillaume Chatelet // Converts an offset into a pointer. 1985314e9bSGuillaume Chatelet const void *forge(size_t offset) { 2085314e9bSGuillaume Chatelet return reinterpret_cast<const void *>(offset); 21961aeb7aSGuillaume Chatelet } 2285314e9bSGuillaume Chatelet 23a786096fSGuillaume Chatelet TEST(LlvmLibcUtilsTest, DistanceToNextAligned) { 24a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_next_aligned<16>(forge(0)), UINT(16)); 25a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_next_aligned<16>(forge(1)), UINT(15)); 26a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_next_aligned<16>(forge(16)), UINT(16)); 27a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_next_aligned<16>(forge(15)), UINT(1)); 28a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_next_aligned<32>(forge(16)), UINT(16)); 2985314e9bSGuillaume Chatelet } 3085314e9bSGuillaume Chatelet 31a786096fSGuillaume Chatelet TEST(LlvmLibcUtilsTest, DistanceToAlignUp) { 32a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_align_up<16>(forge(0)), UINT(0)); 33a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_align_up<16>(forge(1)), UINT(15)); 34a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_align_up<16>(forge(16)), UINT(0)); 35a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_align_up<16>(forge(15)), UINT(1)); 36a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_align_up<32>(forge(16)), UINT(16)); 3704a309ddSGuillaume Chatelet } 3804a309ddSGuillaume Chatelet 39a786096fSGuillaume Chatelet TEST(LlvmLibcUtilsTest, DistanceToAlignDown) { 40a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_align_down<16>(forge(0)), UINT(0)); 41a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_align_down<16>(forge(1)), UINT(1)); 42a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_align_down<16>(forge(16)), UINT(0)); 43a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_align_down<16>(forge(15)), UINT(15)); 44a786096fSGuillaume Chatelet EXPECT_EQ(distance_to_align_down<32>(forge(16)), UINT(16)); 45060a43ceSGuillaume Chatelet } 46060a43ceSGuillaume Chatelet 47060a43ceSGuillaume Chatelet TEST(LlvmLibcUtilsTest, Adjust2) { 48060a43ceSGuillaume Chatelet char a, b; 49060a43ceSGuillaume Chatelet const size_t base_size = 10; 50a786096fSGuillaume Chatelet for (ptrdiff_t I = -2; I < 2; ++I) { 51060a43ceSGuillaume Chatelet auto *p1 = &a; 52060a43ceSGuillaume Chatelet auto *p2 = &b; 53060a43ceSGuillaume Chatelet size_t size = base_size; 54060a43ceSGuillaume Chatelet adjust(I, p1, p2, size); 55060a43ceSGuillaume Chatelet EXPECT_EQ(intptr_t(p1), intptr_t(&a + I)); 56060a43ceSGuillaume Chatelet EXPECT_EQ(intptr_t(p2), intptr_t(&b + I)); 57060a43ceSGuillaume Chatelet EXPECT_EQ(size, base_size - I); 58060a43ceSGuillaume Chatelet } 59060a43ceSGuillaume Chatelet } 60060a43ceSGuillaume Chatelet 61060a43ceSGuillaume Chatelet TEST(LlvmLibcUtilsTest, Align2) { 62060a43ceSGuillaume Chatelet char a, b; 63060a43ceSGuillaume Chatelet const size_t base_size = 10; 64060a43ceSGuillaume Chatelet { 65060a43ceSGuillaume Chatelet auto *p1 = &a; 66060a43ceSGuillaume Chatelet auto *p2 = &b; 67060a43ceSGuillaume Chatelet size_t size = base_size; 68a786096fSGuillaume Chatelet align_to_next_boundary<128, Arg::P1>(p1, p2, size); 69060a43ceSGuillaume Chatelet EXPECT_TRUE(uintptr_t(p1) % 128 == 0); 70a786096fSGuillaume Chatelet EXPECT_GT(p1, &a); 71a786096fSGuillaume Chatelet EXPECT_GT(p2, &b); 72060a43ceSGuillaume Chatelet EXPECT_EQ(size_t(p1 - &a), base_size - size); 73060a43ceSGuillaume Chatelet EXPECT_EQ(size_t(p2 - &b), base_size - size); 74060a43ceSGuillaume Chatelet } 75060a43ceSGuillaume Chatelet { 76060a43ceSGuillaume Chatelet auto *p1 = &a; 77060a43ceSGuillaume Chatelet auto *p2 = &b; 78060a43ceSGuillaume Chatelet size_t size = base_size; 79a786096fSGuillaume Chatelet align_to_next_boundary<128, Arg::P2>(p1, p2, size); 80060a43ceSGuillaume Chatelet EXPECT_TRUE(uintptr_t(p2) % 128 == 0); 81a786096fSGuillaume Chatelet EXPECT_GT(p1, &a); 82a786096fSGuillaume Chatelet EXPECT_GT(p2, &b); 83060a43ceSGuillaume Chatelet EXPECT_EQ(size_t(p1 - &a), base_size - size); 84060a43ceSGuillaume Chatelet EXPECT_EQ(size_t(p2 - &b), base_size - size); 85060a43ceSGuillaume Chatelet } 86060a43ceSGuillaume Chatelet } 87060a43ceSGuillaume Chatelet 882cfae7cdSGuillaume Chatelet TEST(LlvmLibcUtilsTest, DisjointBuffers) { 892cfae7cdSGuillaume Chatelet char buf[3]; 902cfae7cdSGuillaume Chatelet const char *const a = buf + 0; 912cfae7cdSGuillaume Chatelet const char *const b = buf + 1; 922cfae7cdSGuillaume Chatelet EXPECT_TRUE(is_disjoint(a, b, 0)); 932cfae7cdSGuillaume Chatelet EXPECT_TRUE(is_disjoint(a, b, 1)); 942cfae7cdSGuillaume Chatelet EXPECT_FALSE(is_disjoint(a, b, 2)); 952cfae7cdSGuillaume Chatelet 962cfae7cdSGuillaume Chatelet EXPECT_TRUE(is_disjoint(b, a, 0)); 972cfae7cdSGuillaume Chatelet EXPECT_TRUE(is_disjoint(b, a, 1)); 982cfae7cdSGuillaume Chatelet EXPECT_FALSE(is_disjoint(b, a, 2)); 992cfae7cdSGuillaume Chatelet } 1002cfae7cdSGuillaume Chatelet 101f4a35492SGuillaume Chatelet TEST(LlvmLibcUtilsTest, LoadStoreAligned) { 102f4a35492SGuillaume Chatelet const uint64_t init = 0xDEAD'C0DE'BEEF'F00D; 103f4a35492SGuillaume Chatelet CPtr const src = reinterpret_cast<CPtr>(&init); 104f4a35492SGuillaume Chatelet uint64_t store; 105f4a35492SGuillaume Chatelet Ptr const dst = reinterpret_cast<Ptr>(&store); 106f4a35492SGuillaume Chatelet 107f4a35492SGuillaume Chatelet using LoadFun = uint64_t (*)(CPtr); 108f4a35492SGuillaume Chatelet using StoreFun = void (*)(uint64_t, Ptr); 109f4a35492SGuillaume Chatelet 110f4a35492SGuillaume Chatelet { 111f4a35492SGuillaume Chatelet LoadFun ld = load_aligned<uint64_t, uint64_t>; 112f4a35492SGuillaume Chatelet StoreFun st = store_aligned<uint64_t, uint64_t>; 113f4a35492SGuillaume Chatelet const uint64_t loaded = ld(src); 114f4a35492SGuillaume Chatelet EXPECT_EQ(init, loaded); 115f4a35492SGuillaume Chatelet store = 0; 116f4a35492SGuillaume Chatelet st(init, dst); 117f4a35492SGuillaume Chatelet EXPECT_EQ(init, store); 118f4a35492SGuillaume Chatelet } 119f4a35492SGuillaume Chatelet 120f4a35492SGuillaume Chatelet { 121f4a35492SGuillaume Chatelet LoadFun ld = load_aligned<uint64_t, uint32_t, uint32_t>; 122f4a35492SGuillaume Chatelet StoreFun st = store_aligned<uint64_t, uint32_t, uint32_t>; 123f4a35492SGuillaume Chatelet const uint64_t loaded = ld(src); 124f4a35492SGuillaume Chatelet EXPECT_EQ(init, loaded); 125f4a35492SGuillaume Chatelet store = 0; 126f4a35492SGuillaume Chatelet st(init, dst); 127f4a35492SGuillaume Chatelet EXPECT_EQ(init, store); 128f4a35492SGuillaume Chatelet } 129f4a35492SGuillaume Chatelet 130f4a35492SGuillaume Chatelet { 131f4a35492SGuillaume Chatelet LoadFun ld = load_aligned<uint64_t, uint32_t, uint16_t, uint8_t, uint8_t>; 132f4a35492SGuillaume Chatelet StoreFun st = store_aligned<uint64_t, uint32_t, uint16_t, uint8_t, uint8_t>; 133f4a35492SGuillaume Chatelet const uint64_t loaded = ld(src); 134f4a35492SGuillaume Chatelet EXPECT_EQ(init, loaded); 135f4a35492SGuillaume Chatelet store = 0; 136f4a35492SGuillaume Chatelet st(init, dst); 137f4a35492SGuillaume Chatelet EXPECT_EQ(init, store); 138f4a35492SGuillaume Chatelet } 139f4a35492SGuillaume Chatelet } 140f4a35492SGuillaume Chatelet 141*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 142