1 //===-- Unittests for memory_utils ----------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "src/__support/CPP/array.h"
10 #include "src/__support/macros/config.h"
11 #include "src/string/memory_utils/utils.h"
12 #include "test/UnitTest/Test.h"
14 namespace LIBC_NAMESPACE_DECL
{
16 using UINT
= uintptr_t;
18 // Converts an offset into a pointer.
19 const void *forge(size_t offset
) {
20 return reinterpret_cast<const void *>(offset
);
23 TEST(LlvmLibcUtilsTest
, DistanceToNextAligned
) {
24 EXPECT_EQ(distance_to_next_aligned
<16>(forge(0)), UINT(16));
25 EXPECT_EQ(distance_to_next_aligned
<16>(forge(1)), UINT(15));
26 EXPECT_EQ(distance_to_next_aligned
<16>(forge(16)), UINT(16));
27 EXPECT_EQ(distance_to_next_aligned
<16>(forge(15)), UINT(1));
28 EXPECT_EQ(distance_to_next_aligned
<32>(forge(16)), UINT(16));
31 TEST(LlvmLibcUtilsTest
, DistanceToAlignUp
) {
32 EXPECT_EQ(distance_to_align_up
<16>(forge(0)), UINT(0));
33 EXPECT_EQ(distance_to_align_up
<16>(forge(1)), UINT(15));
34 EXPECT_EQ(distance_to_align_up
<16>(forge(16)), UINT(0));
35 EXPECT_EQ(distance_to_align_up
<16>(forge(15)), UINT(1));
36 EXPECT_EQ(distance_to_align_up
<32>(forge(16)), UINT(16));
39 TEST(LlvmLibcUtilsTest
, DistanceToAlignDown
) {
40 EXPECT_EQ(distance_to_align_down
<16>(forge(0)), UINT(0));
41 EXPECT_EQ(distance_to_align_down
<16>(forge(1)), UINT(1));
42 EXPECT_EQ(distance_to_align_down
<16>(forge(16)), UINT(0));
43 EXPECT_EQ(distance_to_align_down
<16>(forge(15)), UINT(15));
44 EXPECT_EQ(distance_to_align_down
<32>(forge(16)), UINT(16));
47 TEST(LlvmLibcUtilsTest
, Adjust2
) {
49 const size_t base_size
= 10;
50 for (ptrdiff_t I
= -2; I
< 2; ++I
) {
53 size_t size
= base_size
;
54 adjust(I
, p1
, p2
, size
);
55 EXPECT_EQ(intptr_t(p1
), intptr_t(&a
+ I
));
56 EXPECT_EQ(intptr_t(p2
), intptr_t(&b
+ I
));
57 EXPECT_EQ(size
, base_size
- I
);
61 TEST(LlvmLibcUtilsTest
, Align2
) {
63 const size_t base_size
= 10;
67 size_t size
= base_size
;
68 align_to_next_boundary
<128, Arg::P1
>(p1
, p2
, size
);
69 EXPECT_TRUE(uintptr_t(p1
) % 128 == 0);
72 EXPECT_EQ(size_t(p1
- &a
), base_size
- size
);
73 EXPECT_EQ(size_t(p2
- &b
), base_size
- size
);
78 size_t size
= base_size
;
79 align_to_next_boundary
<128, Arg::P2
>(p1
, p2
, size
);
80 EXPECT_TRUE(uintptr_t(p2
) % 128 == 0);
83 EXPECT_EQ(size_t(p1
- &a
), base_size
- size
);
84 EXPECT_EQ(size_t(p2
- &b
), base_size
- size
);
88 TEST(LlvmLibcUtilsTest
, DisjointBuffers
) {
90 const char *const a
= buf
+ 0;
91 const char *const b
= buf
+ 1;
92 EXPECT_TRUE(is_disjoint(a
, b
, 0));
93 EXPECT_TRUE(is_disjoint(a
, b
, 1));
94 EXPECT_FALSE(is_disjoint(a
, b
, 2));
96 EXPECT_TRUE(is_disjoint(b
, a
, 0));
97 EXPECT_TRUE(is_disjoint(b
, a
, 1));
98 EXPECT_FALSE(is_disjoint(b
, a
, 2));
101 TEST(LlvmLibcUtilsTest
, LoadStoreAligned
) {
102 const uint64_t init
= 0xDEAD'C0DE'BEEF'F00D;
103 CPtr
const src
= reinterpret_cast<CPtr
>(&init
);
105 Ptr
const dst
= reinterpret_cast<Ptr
>(&store
);
107 using LoadFun
= uint64_t (*)(CPtr
);
108 using StoreFun
= void (*)(uint64_t, Ptr
);
111 LoadFun ld
= load_aligned
<uint64_t, uint64_t>;
112 StoreFun st
= store_aligned
<uint64_t, uint64_t>;
113 const uint64_t loaded
= ld(src
);
114 EXPECT_EQ(init
, loaded
);
117 EXPECT_EQ(init
, store
);
121 LoadFun ld
= load_aligned
<uint64_t, uint32_t, uint32_t>;
122 StoreFun st
= store_aligned
<uint64_t, uint32_t, uint32_t>;
123 const uint64_t loaded
= ld(src
);
124 EXPECT_EQ(init
, loaded
);
127 EXPECT_EQ(init
, store
);
131 LoadFun ld
= load_aligned
<uint64_t, uint32_t, uint16_t, uint8_t, uint8_t>;
132 StoreFun st
= store_aligned
<uint64_t, uint32_t, uint16_t, uint8_t, uint8_t>;
133 const uint64_t loaded
= ld(src
);
134 EXPECT_EQ(init
, loaded
);
137 EXPECT_EQ(init
, store
);
141 } // namespace LIBC_NAMESPACE_DECL