1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 #include "precompiled.hpp"
  25 
  26 #include "utilities/globalDefinitions.hpp"
  27 #include "utilities/powerOfTwo.hpp"
  28 #include "unittest.hpp"
  29 
  30 template <typename T> T max_pow2() {
  31   T max_val = max_value<T>();
  32   return max_val - (max_val >> 1);
  33 }
  34 
  35 template <typename T> static void test_is_power_of_2() {
  36   EXPECT_FALSE(is_power_of_2(T(0)));
  37   EXPECT_FALSE(is_power_of_2(~T(0)));
  38 
  39   // Test true
  40   for (T i = max_pow2<T>(); i > 0; i = (i >> 1)) {
  41     EXPECT_TRUE(is_power_of_2(i)) << "value = " << T(i);
  42   }
  43 
  44   // Test one less
  45   for (T i = max_pow2<T>(); i > 2; i = (i >> 1)) {
  46     EXPECT_FALSE(is_power_of_2(i - 1)) << "value = " << T(i - 1);
  47   }
  48 
  49   // Test one more
  50   for (T i = max_pow2<T>(); i > 1; i = (i >> 1)) {
  51     EXPECT_FALSE(is_power_of_2(i + 1)) << "value = " << T(i + 1);
  52   }
  53 }
  54 
  55 TEST(power_of_2, is_power_of_2) {
  56   test_is_power_of_2<int8_t>();
  57   test_is_power_of_2<int16_t>();
  58   test_is_power_of_2<int32_t>();
  59   test_is_power_of_2<int64_t>();
  60   test_is_power_of_2<int8_t>();
  61   test_is_power_of_2<int16_t>();
  62   test_is_power_of_2<int32_t>();
  63   test_is_power_of_2<int64_t>();
  64 
  65   test_is_power_of_2<jint>();
  66   test_is_power_of_2<jlong>();
  67 }
  68 
  69 template <typename T> void round_up_power_of_2() {
  70   EXPECT_EQ(round_up_power_of_2(T(1)), T(1)) << "value = " << T(1);
  71   EXPECT_EQ(round_up_power_of_2(T(2)), T(2)) << "value = " << T(2);
  72   EXPECT_EQ(round_up_power_of_2(T(3)), T(4)) << "value = " << T(3);
  73   EXPECT_EQ(round_up_power_of_2(T(4)), T(4)) << "value = " << T(4);
  74   EXPECT_EQ(round_up_power_of_2(T(5)), T(8)) << "value = " << T(5);
  75   EXPECT_EQ(round_up_power_of_2(T(6)), T(8)) << "value = " << T(6);
  76   EXPECT_EQ(round_up_power_of_2(T(7)), T(8)) << "value = " << T(7);
  77   EXPECT_EQ(round_up_power_of_2(T(8)), T(8)) << "value = " << T(8);
  78   EXPECT_EQ(round_up_power_of_2(T(9)), T(16)) << "value = " << T(9);
  79   EXPECT_EQ(round_up_power_of_2(T(10)), T(16)) << "value = " << T(10);
  80 
  81   T t_max_pow2 = max_pow2<T>();
  82 
  83   // round_up(any power of two) should return input
  84   for (T pow2 = T(1); pow2 < t_max_pow2; pow2 *= 2) {
  85     EXPECT_EQ(pow2, round_up_power_of_2(pow2))
  86       << "value = " << pow2;
  87   }
  88   EXPECT_EQ(round_up_power_of_2(t_max_pow2), t_max_pow2)
  89     << "value = " << (t_max_pow2);
  90 
  91   // For each pow2 gt 2, round_up(pow2 - 1) should return pow2
  92   for (T pow2 = T(4); pow2 < t_max_pow2; pow2 *= 2) {
  93     EXPECT_EQ(pow2, round_up_power_of_2(pow2 - 1))
  94       << "value = " << pow2;
  95   }
  96   EXPECT_EQ(round_up_power_of_2(t_max_pow2 - 1), t_max_pow2)
  97     << "value = " << (t_max_pow2 - 1);
  98 
  99 }
 100 
 101 TEST(power_of_2, round_up_power_of_2) {
 102   round_up_power_of_2<int8_t>();
 103   round_up_power_of_2<int16_t>();
 104   round_up_power_of_2<int32_t>();
 105   round_up_power_of_2<int64_t>();
 106   round_up_power_of_2<uint8_t>();
 107   round_up_power_of_2<uint16_t>();
 108   round_up_power_of_2<uint32_t>();
 109   round_up_power_of_2<uint64_t>();
 110 }
 111 
 112 template <typename T> void round_down_power_of_2() {
 113   EXPECT_EQ(round_down_power_of_2(T(1)), T(1)) << "value = " << T(1);
 114   EXPECT_EQ(round_down_power_of_2(T(2)), T(2)) << "value = " << T(2);
 115   EXPECT_EQ(round_down_power_of_2(T(3)), T(2)) << "value = " << T(3);
 116   EXPECT_EQ(round_down_power_of_2(T(4)), T(4)) << "value = " << T(4);
 117   EXPECT_EQ(round_down_power_of_2(T(5)), T(4)) << "value = " << T(5);
 118   EXPECT_EQ(round_down_power_of_2(T(6)), T(4)) << "value = " << T(6);
 119   EXPECT_EQ(round_down_power_of_2(T(7)), T(4)) << "value = " << T(7);
 120   EXPECT_EQ(round_down_power_of_2(T(8)), T(8)) << "value = " << T(8);
 121   EXPECT_EQ(round_down_power_of_2(T(9)), T(8)) << "value = " << T(9);
 122   EXPECT_EQ(round_down_power_of_2(T(10)), T(8)) << "value = " << T(10);
 123 
 124   T t_max_pow2 = max_pow2<T>();
 125 
 126   // For each pow2 >= 2:
 127   // - round_down(pow2) should return pow2
 128   // - round_down(pow2 + 1) should return pow2
 129   // - round_down(pow2 - 1) should return pow2 / 2
 130   for (T pow2 = T(2); pow2 < t_max_pow2; pow2 = pow2 * 2) {
 131     EXPECT_EQ(pow2, round_down_power_of_2(pow2))
 132       << "value = " << pow2;
 133     EXPECT_EQ(pow2, round_down_power_of_2(pow2 + 1))
 134       << "value = " << pow2;
 135     EXPECT_EQ(pow2 / 2, round_down_power_of_2(pow2 - 1))
 136       << "value = " << (pow2 / 2);
 137   }
 138   EXPECT_EQ(round_down_power_of_2(t_max_pow2), t_max_pow2)
 139     << "value = " << (t_max_pow2);
 140   EXPECT_EQ(round_down_power_of_2(t_max_pow2 + 1), t_max_pow2)
 141     << "value = " << (t_max_pow2 + 1);
 142   EXPECT_EQ(round_down_power_of_2(t_max_pow2 - 1), t_max_pow2 / 2)
 143     << "value = " << (t_max_pow2 - 1);
 144 }
 145 
 146 TEST(power_of_2, round_down_power_of_2) {
 147   round_down_power_of_2<int8_t>();
 148   round_down_power_of_2<int16_t>();
 149   round_down_power_of_2<int32_t>();
 150   round_down_power_of_2<int64_t>();
 151   round_down_power_of_2<uint8_t>();
 152   round_down_power_of_2<uint16_t>();
 153   round_down_power_of_2<uint32_t>();
 154   round_down_power_of_2<uint64_t>();
 155 }
 156 
 157 template <typename T> void next_power_of_2() {
 158   EXPECT_EQ(next_power_of_2(T(0)), T(1)) << "value = " << T(0);
 159   EXPECT_EQ(next_power_of_2(T(1)), T(2)) << "value = " << T(1);
 160   EXPECT_EQ(next_power_of_2(T(2)), T(4)) << "value = " << T(2);
 161   EXPECT_EQ(next_power_of_2(T(3)), T(4)) << "value = " << T(3);
 162   EXPECT_EQ(next_power_of_2(T(4)), T(8)) << "value = " << T(4);
 163   EXPECT_EQ(next_power_of_2(T(5)), T(8)) << "value = " << T(5);
 164   EXPECT_EQ(next_power_of_2(T(6)), T(8)) << "value = " << T(6);
 165   EXPECT_EQ(next_power_of_2(T(7)), T(8)) << "value = " << T(7);
 166   EXPECT_EQ(next_power_of_2(T(8)), T(16)) << "value = " << T(8);
 167   EXPECT_EQ(next_power_of_2(T(9)), T(16)) << "value = " << T(9);
 168   EXPECT_EQ(next_power_of_2(T(10)), T(16)) << "value = " << T(10);
 169 
 170   T t_max_pow2 = max_pow2<T>();
 171 
 172   // next(pow2 - 1) should return pow2
 173   for (T pow2 = T(1); pow2 < t_max_pow2; pow2 = pow2 * 2) {
 174     EXPECT_EQ(pow2, next_power_of_2(pow2 - 1))
 175       << "value = " << pow2 - 1;
 176   }
 177   EXPECT_EQ(next_power_of_2(t_max_pow2 - 1), t_max_pow2)
 178     << "value = " << (t_max_pow2 - 1);
 179 
 180   // next(pow2) should return pow2 * 2
 181   for (T pow2 = T(1); pow2 < t_max_pow2 / 2; pow2 = pow2 * 2) {
 182     EXPECT_EQ(pow2 * 2, next_power_of_2(pow2))
 183       << "value = " << pow2;
 184   }
 185 }
 186 
 187 TEST(power_of_2, next_power_of_2) {
 188   next_power_of_2<int8_t>();
 189   next_power_of_2<int16_t>();
 190   next_power_of_2<int32_t>();
 191   next_power_of_2<int64_t>();
 192   next_power_of_2<uint8_t>();
 193   next_power_of_2<uint16_t>();
 194   next_power_of_2<uint32_t>();
 195   next_power_of_2<uint64_t>();
 196 }