MathIntrinsicsTests.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/UnitTest/TestTypes.h>
  9. #include <AzCore/Math/MathIntrinsics.h>
  10. namespace UnitTest
  11. {
  12. TEST(MathIntrinsics, CountLeadingZeros)
  13. {
  14. // Split up the binary literal in by every 4 bits
  15. {
  16. constexpr uint32_t leadingZero32 = 0b1000'0000'0000'0010'0000'0000'0000'0010;
  17. EXPECT_EQ(0, az_clz_u32(leadingZero32));
  18. EXPECT_EQ(32, az_clz_u64(leadingZero32));
  19. }
  20. {
  21. constexpr uint64_t leadingZero64 = 0b0000'0100'1111'1011'0001'1000'0010'0110'1000'0000'0000'0010'0000'0000'0000'0010ULL;
  22. EXPECT_EQ(5, az_clz_u64(leadingZero64));
  23. }
  24. #if defined(AZ_COMPILER_MSVC)
  25. {
  26. // All Zero case
  27. // When using the clang compiler, this macro calls __builtin_clz,
  28. // whose return value is undefined when the input is 0
  29. constexpr uint32_t leadingZero32 = 0b0000'0000'0000'0000'0000'0000'0000'0000;
  30. EXPECT_EQ(32, az_clz_u32(leadingZero32));
  31. EXPECT_EQ(64, az_clz_u64(leadingZero32));
  32. }
  33. #endif
  34. {
  35. // All One case
  36. constexpr uint32_t leadingZero32 = 0b1111'1111'1111'1111'1111'1111'1111'1111;
  37. EXPECT_EQ(0, az_clz_u32(leadingZero32));
  38. EXPECT_EQ(32, az_clz_u64(leadingZero32));
  39. }
  40. }
  41. TEST(MathIntrinsics, CountTrailingZeros)
  42. {
  43. // Split up the binary literal in by every 4 bits
  44. {
  45. constexpr uint32_t trailingZero32 = 0b1000'0000'0000'0010'0000'0000'0010'0000;
  46. EXPECT_EQ(5, az_ctz_u32(trailingZero32));
  47. EXPECT_EQ(5, az_ctz_u64(trailingZero32));
  48. }
  49. {
  50. constexpr uint64_t trailingZero64 = 0b0000'0100'1111'1011'0001'1000'0010'0110'1000'0000'0000'0010'0000'0000'0000'0010ULL;
  51. EXPECT_EQ(1, az_ctz_u64(trailingZero64));
  52. }
  53. #if defined(AZ_COMPILER_MSVC)
  54. {
  55. // All Zero case
  56. // When using the clang compiler, this macro calls __builtin_ctz,
  57. // whose return value is undefined when the input is 0
  58. constexpr uint32_t trailingZero32 = 0b0000'0000'0000'0000'0000'0000'0000'0000;
  59. EXPECT_EQ(32, az_ctz_u32(trailingZero32));
  60. EXPECT_EQ(64, az_ctz_u64(trailingZero32));
  61. }
  62. #endif
  63. {
  64. // All One case
  65. constexpr uint32_t trailingZero32 = 0b1111'1111'1111'1111'1111'1111'1111'1111;
  66. EXPECT_EQ(0, az_ctz_u32(trailingZero32));
  67. EXPECT_EQ(0, az_ctz_u64(trailingZero32));
  68. }
  69. }
  70. TEST(MathIntrinsics, CountOneBits)
  71. {
  72. // Split up the binary literal in by every 4 bits
  73. {
  74. constexpr uint32_t oneBits32 = 0b1010'1010'1011'1010'0010'0000'1010'0001;
  75. EXPECT_EQ(13, az_popcnt_u32(oneBits32));
  76. EXPECT_EQ(13, az_popcnt_u64(oneBits32));
  77. }
  78. {
  79. constexpr uint64_t oneBits64 = 0b0000'0100'1111'1011'0001'1000'0010'0110'1000'0000'1111'0010'0001'1000'0000'0010ULL;
  80. EXPECT_EQ(22, az_popcnt_u64(oneBits64));
  81. }
  82. {
  83. // All Zero case
  84. constexpr uint32_t oneBits32 = 0b0000'0000'0000'0000'0000'0000'0000'0000;
  85. EXPECT_EQ(0, az_popcnt_u32(oneBits32));
  86. EXPECT_EQ(0, az_popcnt_u64(oneBits32));
  87. }
  88. {
  89. // All One case
  90. constexpr uint32_t oneBits32 = 0b1111'1111'1111'1111'1111'1111'1111'1111;
  91. EXPECT_EQ(32, az_popcnt_u32(oneBits32));
  92. EXPECT_EQ(32, az_popcnt_u64(oneBits32));
  93. }
  94. {
  95. // Bitwise-not cases(~0)
  96. EXPECT_EQ(32, az_popcnt_u32(uint32_t(~0LL)));
  97. EXPECT_EQ(31, az_popcnt_u32(uint32_t(~1LL)));
  98. EXPECT_EQ(64, az_popcnt_u64(uint64_t(~0LL)));
  99. EXPECT_EQ(63, az_popcnt_u64(uint64_t(~1LL)));
  100. }
  101. }
  102. }