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 
9*f362aea4SSiva Chandra Reddy #include "src/__support/CPP/Array.h"
1085314e9bSGuillaume Chatelet #include "src/string/memory_utils/utils.h"
1185314e9bSGuillaume Chatelet #include "utils/UnitTest/Test.h"
1285314e9bSGuillaume Chatelet 
1385314e9bSGuillaume Chatelet namespace __llvm_libc {
1485314e9bSGuillaume Chatelet 
TEST(LlvmLibcUtilsTest,IsPowerOfTwoOrZero)151df0dbfcSMichael Jones TEST(LlvmLibcUtilsTest, IsPowerOfTwoOrZero) {
162a6ef2aeSSiva Chandra Reddy   static const cpp::Array<bool, 65> kExpectedValues{
1785314e9bSGuillaume Chatelet       1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 0-15
1885314e9bSGuillaume Chatelet       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
1985314e9bSGuillaume Chatelet       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47
2085314e9bSGuillaume Chatelet       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 48-63
2185314e9bSGuillaume Chatelet       1                                               // 64
222a6ef2aeSSiva Chandra Reddy   };
2385314e9bSGuillaume Chatelet   for (size_t i = 0; i < kExpectedValues.size(); ++i)
2485314e9bSGuillaume Chatelet     EXPECT_EQ(is_power2_or_zero(i), kExpectedValues[i]);
2585314e9bSGuillaume Chatelet }
2685314e9bSGuillaume Chatelet 
TEST(LlvmLibcUtilsTest,IsPowerOfTwo)271df0dbfcSMichael Jones TEST(LlvmLibcUtilsTest, IsPowerOfTwo) {
282a6ef2aeSSiva Chandra Reddy   static const cpp::Array<bool, 65> kExpectedValues{
2985314e9bSGuillaume Chatelet       0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 0-15
3085314e9bSGuillaume Chatelet       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
3185314e9bSGuillaume Chatelet       1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47
3285314e9bSGuillaume Chatelet       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 48-63
3385314e9bSGuillaume Chatelet       1                                               // 64
342a6ef2aeSSiva Chandra Reddy   };
3585314e9bSGuillaume Chatelet   for (size_t i = 0; i < kExpectedValues.size(); ++i)
3685314e9bSGuillaume Chatelet     EXPECT_EQ(is_power2(i), kExpectedValues[i]);
3785314e9bSGuillaume Chatelet }
3885314e9bSGuillaume Chatelet 
TEST(LlvmLibcUtilsTest,Log2)391df0dbfcSMichael Jones TEST(LlvmLibcUtilsTest, Log2) {
402a6ef2aeSSiva Chandra Reddy   static const cpp::Array<size_t, 65> kExpectedValues{
4185314e9bSGuillaume Chatelet       0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, // 0-15
4285314e9bSGuillaume Chatelet       4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 16-31
4385314e9bSGuillaume Chatelet       5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 32-47
4485314e9bSGuillaume Chatelet       5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 48-63
4585314e9bSGuillaume Chatelet       6                                               // 64
462a6ef2aeSSiva Chandra Reddy   };
4785314e9bSGuillaume Chatelet   for (size_t i = 0; i < kExpectedValues.size(); ++i)
4885314e9bSGuillaume Chatelet     EXPECT_EQ(log2(i), kExpectedValues[i]);
4985314e9bSGuillaume Chatelet }
5085314e9bSGuillaume Chatelet 
TEST(LlvmLibcUtilsTest,LEPowerOf2)511df0dbfcSMichael Jones TEST(LlvmLibcUtilsTest, LEPowerOf2) {
522a6ef2aeSSiva Chandra Reddy   static const cpp::Array<size_t, 65> kExpectedValues{
5385314e9bSGuillaume Chatelet       0,  1,  2,  2,  4,  4,  4,  4,  8,  8,  8,  8,  8,  8,  8,  8,  // 0-15
5485314e9bSGuillaume Chatelet       16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, // 16-31
5585314e9bSGuillaume Chatelet       32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 32-47
5685314e9bSGuillaume Chatelet       32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 48-63
5785314e9bSGuillaume Chatelet       64                                                              // 64
582a6ef2aeSSiva Chandra Reddy   };
5985314e9bSGuillaume Chatelet   for (size_t i = 0; i < kExpectedValues.size(); ++i)
6085314e9bSGuillaume Chatelet     EXPECT_EQ(le_power2(i), kExpectedValues[i]);
6185314e9bSGuillaume Chatelet }
6285314e9bSGuillaume Chatelet 
TEST(LlvmLibcUtilsTest,GEPowerOf2)631df0dbfcSMichael Jones TEST(LlvmLibcUtilsTest, GEPowerOf2) {
642a6ef2aeSSiva Chandra Reddy   static const cpp::Array<size_t, 66> kExpectedValues{
6585314e9bSGuillaume Chatelet       0,  1,  2,  4,  4,  8,  8,  8,  8,  16, 16, 16, 16, 16, 16, 16, // 0-15
6685314e9bSGuillaume Chatelet       16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, // 16-31
6785314e9bSGuillaume Chatelet       32, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 32-47
6885314e9bSGuillaume Chatelet       64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, // 48-63
6985314e9bSGuillaume Chatelet       64, 128                                                         // 64-65
702a6ef2aeSSiva Chandra Reddy   };
7185314e9bSGuillaume Chatelet   for (size_t i = 0; i < kExpectedValues.size(); ++i)
7285314e9bSGuillaume Chatelet     EXPECT_EQ(ge_power2(i), kExpectedValues[i]);
7385314e9bSGuillaume Chatelet }
7485314e9bSGuillaume Chatelet 
7585314e9bSGuillaume Chatelet using I = intptr_t;
7685314e9bSGuillaume Chatelet 
7785314e9bSGuillaume Chatelet // Converts an offset into a pointer.
forge(size_t offset)7885314e9bSGuillaume Chatelet const void *forge(size_t offset) {
7985314e9bSGuillaume Chatelet   return reinterpret_cast<const void *>(offset);
80961aeb7aSGuillaume Chatelet }
8185314e9bSGuillaume Chatelet 
TEST(LlvmLibcUtilsTest,OffsetToNextAligned)821df0dbfcSMichael Jones TEST(LlvmLibcUtilsTest, OffsetToNextAligned) {
8385314e9bSGuillaume Chatelet   EXPECT_EQ(offset_to_next_aligned<16>(forge(0)), I(0));
8485314e9bSGuillaume Chatelet   EXPECT_EQ(offset_to_next_aligned<16>(forge(1)), I(15));
8585314e9bSGuillaume Chatelet   EXPECT_EQ(offset_to_next_aligned<16>(forge(16)), I(0));
8685314e9bSGuillaume Chatelet   EXPECT_EQ(offset_to_next_aligned<16>(forge(15)), I(1));
8785314e9bSGuillaume Chatelet   EXPECT_EQ(offset_to_next_aligned<32>(forge(16)), I(16));
8885314e9bSGuillaume Chatelet }
8985314e9bSGuillaume Chatelet 
TEST(LlvmLibcUtilsTest,OffsetFromLastAligned)901df0dbfcSMichael Jones TEST(LlvmLibcUtilsTest, OffsetFromLastAligned) {
9104a309ddSGuillaume Chatelet   EXPECT_EQ(offset_from_last_aligned<16>(forge(0)), I(0));
9204a309ddSGuillaume Chatelet   EXPECT_EQ(offset_from_last_aligned<16>(forge(1)), I(1));
9304a309ddSGuillaume Chatelet   EXPECT_EQ(offset_from_last_aligned<16>(forge(16)), I(0));
9404a309ddSGuillaume Chatelet   EXPECT_EQ(offset_from_last_aligned<16>(forge(15)), I(15));
9504a309ddSGuillaume Chatelet   EXPECT_EQ(offset_from_last_aligned<32>(forge(16)), I(16));
9604a309ddSGuillaume Chatelet }
9704a309ddSGuillaume Chatelet 
TEST(LlvmLibcUtilsTest,OffsetToNextCacheLine)981df0dbfcSMichael Jones TEST(LlvmLibcUtilsTest, OffsetToNextCacheLine) {
9985314e9bSGuillaume Chatelet   EXPECT_GT(LLVM_LIBC_CACHELINE_SIZE, 0);
10085314e9bSGuillaume Chatelet   EXPECT_EQ(offset_to_next_cache_line(forge(0)), I(0));
10185314e9bSGuillaume Chatelet   EXPECT_EQ(offset_to_next_cache_line(forge(1)),
10285314e9bSGuillaume Chatelet             I(LLVM_LIBC_CACHELINE_SIZE - 1));
10385314e9bSGuillaume Chatelet   EXPECT_EQ(offset_to_next_cache_line(forge(LLVM_LIBC_CACHELINE_SIZE)), I(0));
10485314e9bSGuillaume Chatelet   EXPECT_EQ(offset_to_next_cache_line(forge(LLVM_LIBC_CACHELINE_SIZE - 1)),
10585314e9bSGuillaume Chatelet             I(1));
10685314e9bSGuillaume Chatelet }
10785314e9bSGuillaume Chatelet } // namespace __llvm_libc
108