142 lines · cpp
1//===-- Unittests for memory_utils ----------------------------------------===//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/array.h"10#include "src/__support/macros/config.h"11#include "src/string/memory_utils/utils.h"12#include "test/UnitTest/Test.h"13 14namespace LIBC_NAMESPACE_DECL {15 16using UINT = uintptr_t;17 18// Converts an offset into a pointer.19const void *forge(size_t offset) {20 return reinterpret_cast<const void *>(offset);21}22 23TEST(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));29}30 31TEST(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));37}38 39TEST(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));45}46 47TEST(LlvmLibcUtilsTest, Adjust2) {48 char a, b;49 const size_t base_size = 10;50 for (uintptr_t i = 0; i < 4; ++i) {51 auto *p1 = &a;52 auto *p2 = &b;53 size_t size = base_size;54 adjust(static_cast<ptrdiff_t>(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);58 }59}60 61TEST(LlvmLibcUtilsTest, Align2) {62 char a, b;63 const size_t base_size = 10;64 {65 auto *p1 = &a;66 auto *p2 = &b;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);70 EXPECT_GT(p1, &a);71 EXPECT_GT(p2, &b);72 EXPECT_EQ(size_t(p1 - &a), base_size - size);73 EXPECT_EQ(size_t(p2 - &b), base_size - size);74 }75 {76 auto *p1 = &a;77 auto *p2 = &b;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);81 EXPECT_GT(p1, &a);82 EXPECT_GT(p2, &b);83 EXPECT_EQ(size_t(p1 - &a), base_size - size);84 EXPECT_EQ(size_t(p2 - &b), base_size - size);85 }86}87 88TEST(LlvmLibcUtilsTest, DisjointBuffers) {89 char buf[3];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));95 96 EXPECT_TRUE(is_disjoint(b, a, 0));97 EXPECT_TRUE(is_disjoint(b, a, 1));98 EXPECT_FALSE(is_disjoint(b, a, 2));99}100 101TEST(LlvmLibcUtilsTest, LoadStoreAligned) {102 const uint64_t init = 0xDEAD'C0DE'BEEF'F00D;103 CPtr const src = reinterpret_cast<CPtr>(&init);104 uint64_t store;105 Ptr const dst = reinterpret_cast<Ptr>(&store);106 107 using LoadFun = uint64_t (*)(CPtr);108 using StoreFun = void (*)(uint64_t, Ptr);109 110 {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);115 store = 0;116 st(init, dst);117 EXPECT_EQ(init, store);118 }119 120 {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);125 store = 0;126 st(init, dst);127 EXPECT_EQ(init, store);128 }129 130 {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);135 store = 0;136 st(init, dst);137 EXPECT_EQ(init, store);138 }139}140 141} // namespace LIBC_NAMESPACE_DECL142