[orc-rt] Add preliminary math.h header and basic operations.

The initial operations, isPowerOf2 and nextPowerOf2 will be used in an upcoming
patch to add support for bitmask-enums.
This commit is contained in:
Lang Hames 2025-08-21 17:07:34 +10:00
parent 8a10fbb2cb
commit 2380d0ad1d
4 changed files with 115 additions and 0 deletions

View File

@ -1,5 +1,6 @@
set(ORC_RT_HEADERS
orc-rt-c/orc-rt.h
orc-rt/math.h
orc-rt/span.h
)

View File

@ -0,0 +1,35 @@
//===--------- math.h - Math helpers for the ORC runtime --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Math helper functions for the ORC runtime.
//
//===----------------------------------------------------------------------===//
#ifndef ORC_RT_MATH_H
#define ORC_RT_MATH_H
#include <cstdint>
#include <limits>
namespace orc_rt {
/// Test whether the given value is a power of 2.
template <typename T> constexpr bool isPowerOf2(T Val) noexcept {
return Val != 0 && (Val & (Val - 1)) == 0;
}
/// Calculates the next power of 2.
template <typename T> constexpr T nextPowerOf2(T Val) noexcept {
for (size_t I = 1; I < std::numeric_limits<T>::digits; I <<= 1)
Val |= (Val >> I);
return Val + 1;
}
} // namespace orc_rt
#endif // ORC_RT_MATH_H

View File

@ -12,6 +12,7 @@ function(add_orc_rt_unittest test_dirname)
endfunction()
add_orc_rt_unittest(CoreTests
math-test.cpp
span-test.cpp
DISABLE_LLVM_LINK_LLVM_DYLIB
)

View File

@ -0,0 +1,78 @@
//===- math-test.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Tests for orc-rt's math.h APIs.
//
//===----------------------------------------------------------------------===//
#include "orc-rt/math.h"
#include "gtest/gtest.h"
using namespace orc_rt;
TEST(STLExtrasTest, isPowerOf2) {
// Test [0..16]
EXPECT_FALSE(isPowerOf2(0x00));
EXPECT_TRUE(isPowerOf2(0x01));
EXPECT_TRUE(isPowerOf2(0x02));
EXPECT_FALSE(isPowerOf2(0x03));
EXPECT_TRUE(isPowerOf2(0x04));
EXPECT_FALSE(isPowerOf2(0x05));
EXPECT_FALSE(isPowerOf2(0x06));
EXPECT_FALSE(isPowerOf2(0x07));
EXPECT_TRUE(isPowerOf2(0x08));
EXPECT_FALSE(isPowerOf2(0x09));
EXPECT_FALSE(isPowerOf2(0x0A));
EXPECT_FALSE(isPowerOf2(0x0B));
EXPECT_FALSE(isPowerOf2(0x0C));
EXPECT_FALSE(isPowerOf2(0x0D));
EXPECT_FALSE(isPowerOf2(0x0E));
EXPECT_FALSE(isPowerOf2(0x0F));
EXPECT_TRUE(isPowerOf2(0x10));
// Test some higher powers of two and their adjacent values.
EXPECT_FALSE(isPowerOf2(0x1F));
EXPECT_TRUE(isPowerOf2(0x20));
EXPECT_FALSE(isPowerOf2(0x21));
EXPECT_FALSE(isPowerOf2(0x3F));
EXPECT_TRUE(isPowerOf2(0x40));
EXPECT_FALSE(isPowerOf2(0x41));
EXPECT_FALSE(isPowerOf2(0x7F));
EXPECT_TRUE(isPowerOf2(0x80));
EXPECT_FALSE(isPowerOf2(0x81));
// Test larger values.
EXPECT_FALSE(isPowerOf2(0x3fffffff));
EXPECT_TRUE(isPowerOf2(0x40000000));
EXPECT_FALSE(isPowerOf2(0x40000001));
// Test negatives.
EXPECT_FALSE(isPowerOf2(-1));
}
TEST(STLExtrasTest, nextPowerOf2) {
EXPECT_EQ(nextPowerOf2(0x00), (1 << 0));
EXPECT_EQ(nextPowerOf2(0x01), (1 << 1));
EXPECT_EQ(nextPowerOf2(0x02), (1 << 2));
EXPECT_EQ(nextPowerOf2(0x03), (1 << 2));
EXPECT_EQ(nextPowerOf2(0x04), (1 << 3));
EXPECT_EQ(nextPowerOf2(0x05), (1 << 3));
EXPECT_EQ(nextPowerOf2(0x06), (1 << 3));
EXPECT_EQ(nextPowerOf2(0x07), (1 << 3));
EXPECT_EQ(nextPowerOf2(0x08), (1 << 4));
EXPECT_EQ(nextPowerOf2(0x09), (1 << 4));
EXPECT_EQ(nextPowerOf2(0x0a), (1 << 4));
EXPECT_EQ(nextPowerOf2(0x0b), (1 << 4));
EXPECT_EQ(nextPowerOf2(0x0c), (1 << 4));
EXPECT_EQ(nextPowerOf2(0x0d), (1 << 4));
EXPECT_EQ(nextPowerOf2(0x0e), (1 << 4));
EXPECT_EQ(nextPowerOf2(0x0f), (1 << 4));
EXPECT_EQ(nextPowerOf2(0x10), (1 << 5));
}