/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include namespace UnitTest { TEST(MathIntrinsics, CountLeadingZeros) { // Split up the binary literal in by every 4 bits { constexpr uint32_t leadingZero32 = 0b1000'0000'0000'0010'0000'0000'0000'0010; EXPECT_EQ(0, az_clz_u32(leadingZero32)); EXPECT_EQ(32, az_clz_u64(leadingZero32)); } { constexpr uint64_t leadingZero64 = 0b0000'0100'1111'1011'0001'1000'0010'0110'1000'0000'0000'0010'0000'0000'0000'0010ULL; EXPECT_EQ(5, az_clz_u64(leadingZero64)); } #if defined(AZ_COMPILER_MSVC) { // All Zero case // When using the clang compiler, this macro calls __builtin_clz, // whose return value is undefined when the input is 0 constexpr uint32_t leadingZero32 = 0b0000'0000'0000'0000'0000'0000'0000'0000; EXPECT_EQ(32, az_clz_u32(leadingZero32)); EXPECT_EQ(64, az_clz_u64(leadingZero32)); } #endif { // All One case constexpr uint32_t leadingZero32 = 0b1111'1111'1111'1111'1111'1111'1111'1111; EXPECT_EQ(0, az_clz_u32(leadingZero32)); EXPECT_EQ(32, az_clz_u64(leadingZero32)); } } TEST(MathIntrinsics, CountTrailingZeros) { // Split up the binary literal in by every 4 bits { constexpr uint32_t trailingZero32 = 0b1000'0000'0000'0010'0000'0000'0010'0000; EXPECT_EQ(5, az_ctz_u32(trailingZero32)); EXPECT_EQ(5, az_ctz_u64(trailingZero32)); } { constexpr uint64_t trailingZero64 = 0b0000'0100'1111'1011'0001'1000'0010'0110'1000'0000'0000'0010'0000'0000'0000'0010ULL; EXPECT_EQ(1, az_ctz_u64(trailingZero64)); } #if defined(AZ_COMPILER_MSVC) { // All Zero case // When using the clang compiler, this macro calls __builtin_ctz, // whose return value is undefined when the input is 0 constexpr uint32_t trailingZero32 = 0b0000'0000'0000'0000'0000'0000'0000'0000; EXPECT_EQ(32, az_ctz_u32(trailingZero32)); EXPECT_EQ(64, az_ctz_u64(trailingZero32)); } #endif { // All One case constexpr uint32_t trailingZero32 = 0b1111'1111'1111'1111'1111'1111'1111'1111; EXPECT_EQ(0, az_ctz_u32(trailingZero32)); EXPECT_EQ(0, az_ctz_u64(trailingZero32)); } } TEST(MathIntrinsics, CountOneBits) { // Split up the binary literal in by every 4 bits { constexpr uint32_t oneBits32 = 0b1010'1010'1011'1010'0010'0000'1010'0001; EXPECT_EQ(13, az_popcnt_u32(oneBits32)); EXPECT_EQ(13, az_popcnt_u64(oneBits32)); } { constexpr uint64_t oneBits64 = 0b0000'0100'1111'1011'0001'1000'0010'0110'1000'0000'1111'0010'0001'1000'0000'0010ULL; EXPECT_EQ(22, az_popcnt_u64(oneBits64)); } { // All Zero case constexpr uint32_t oneBits32 = 0b0000'0000'0000'0000'0000'0000'0000'0000; EXPECT_EQ(0, az_popcnt_u32(oneBits32)); EXPECT_EQ(0, az_popcnt_u64(oneBits32)); } { // All One case constexpr uint32_t oneBits32 = 0b1111'1111'1111'1111'1111'1111'1111'1111; EXPECT_EQ(32, az_popcnt_u32(oneBits32)); EXPECT_EQ(32, az_popcnt_u64(oneBits32)); } { // Bitwise-not cases(~0) EXPECT_EQ(32, az_popcnt_u32(uint32_t(~0LL))); EXPECT_EQ(31, az_popcnt_u32(uint32_t(~1LL))); EXPECT_EQ(64, az_popcnt_u64(uint64_t(~0LL))); EXPECT_EQ(63, az_popcnt_u64(uint64_t(~1LL))); } } }