gem5  v22.1.0.0
intmath.test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 ARM Limited
3  *
4  * The license below extends only to copyright in the software and shall
5  * not be construed as granting a license to any other intellectual
6  * property including but not limited to intellectual property relating
7  * to a hardware implementation of the functionality of the software
8  * licensed hereunder. You may use the software subject to the license
9  * terms below provided that you ensure that this notice is replicated
10  * unmodified and in its entirety in all distributions of the software,
11  * modified or unmodified, in source code or in binary form.
12  *
13  * Copyright (c) 2019 The Regents of the University of California
14  * All rights reserved
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions are
18  * met: redistributions of source code must retain the above copyright
19  * notice, this list of conditions and the following disclaimer;
20  * redistributions in binary form must reproduce the above copyright
21  * notice, this list of conditions and the following disclaimer in the
22  * documentation and/or other materials provided with the distribution;
23  * neither the name of the copyright holders nor the names of its
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 #include <gtest/gtest.h>
41 #include <tuple>
42 
43 #include "base/intmath.hh"
44 
45 using namespace gem5;
46 
47 TEST(IntmathTest, isPowerOf2)
48 {
49  EXPECT_TRUE(isPowerOf2(1));
50  EXPECT_TRUE(isPowerOf2(32));
51  EXPECT_TRUE(isPowerOf2(65536));
52  EXPECT_TRUE(isPowerOf2(131072));
53  EXPECT_TRUE(isPowerOf2(262144));
54  EXPECT_FALSE(isPowerOf2(0));
55  EXPECT_FALSE(isPowerOf2(36));
56  EXPECT_FALSE(isPowerOf2(2521));
57  EXPECT_FALSE(isPowerOf2(1679616));
58 }
59 
60 TEST(IntmathTest, floorLog2)
61 {
62  EXPECT_EQ(0, floorLog2(1));
63  EXPECT_EQ(4, floorLog2(16));
64  EXPECT_EQ(4, floorLog2(31));
65  EXPECT_EQ(5, floorLog2(36));
66  EXPECT_EQ(8, floorLog2(436));
67  EXPECT_EQ(16, floorLog2(65537));
68  EXPECT_EQ(20, floorLog2(1783592));
69  EXPECT_EQ(41, floorLog2(2821109907456));
70 
71  // Test unsigned integers of various sizes.
72  EXPECT_EQ(0, floorLog2((uint8_t)1));
73  EXPECT_EQ(0, floorLog2((uint16_t)1));
74  EXPECT_EQ(0, floorLog2((uint32_t)1));
75  EXPECT_EQ(0, floorLog2((uint64_t)1));
76 
77  // Test signed integers of various sizes.
78  EXPECT_EQ(0, floorLog2((int8_t)1));
79  EXPECT_EQ(0, floorLog2((int16_t)1));
80  EXPECT_EQ(0, floorLog2((int32_t)1));
81  EXPECT_EQ(0, floorLog2((int64_t)1));
82 }
83 
84 /* The IntmathDeathTest floorLog2 test is dependent on an assert being
85  * triggered. We therefore only run this test for .debug and .opt (where
86  * `TRACING_ON == 1`).
87  */
88 #if TRACING_ON
89 TEST(IntmathDeathTest, floorLog2)
90 {
91  // Verify a non-positive input triggers an assert.
92  EXPECT_DEATH_IF_SUPPORTED(floorLog2(0), "x > 0");
93 }
94 #endif
95 
96 TEST(IntmathTest, ceilLog2)
97 {
98  EXPECT_EQ(0, ceilLog2(1));
99  EXPECT_EQ(4, ceilLog2(16));
100  EXPECT_EQ(5, ceilLog2(31));
101  EXPECT_EQ(6, ceilLog2(36));
102  EXPECT_EQ(9, ceilLog2(436));
103  EXPECT_EQ(17, ceilLog2(65537));
104  EXPECT_EQ(21, ceilLog2(1783592));
105  EXPECT_EQ(42, ceilLog2(2821109907456));
106 }
107 
108 
109 TEST(IntmathTest, divCeil)
110 {
111  EXPECT_EQ(5, divCeil(55, 13));
112  EXPECT_EQ(90, divCeil(7922, 89));
113  EXPECT_EQ(4, divCeil(4800, 1442));
114  EXPECT_EQ(4, divCeil(75, 24));
115  EXPECT_EQ(46, divCeil(451, 10));
116 }
117 
118 TEST(IntmathTest, mulUnsignedNarrow)
119 {
120  uint8_t a = 0xff;
121  uint8_t b = 0x02;
122  uint8_t hi;
123  uint8_t low;
124  mulUnsigned<uint8_t>(hi, low, a, b);
125  EXPECT_EQ(hi, 0x1);
126  EXPECT_EQ(low, 0xfe);
127 
128  a = 14;
129  b = 9;
130  mulUnsigned<uint8_t>(hi, low, a, b);
131  EXPECT_EQ(hi, 0);
132  EXPECT_EQ(low, 0x7e);
133 
134  a = 0;
135  b = 0x55;
136  mulUnsigned<uint8_t>(hi, low, a, b);
137  EXPECT_EQ(hi, 0);
138  EXPECT_EQ(low, 0);
139 }
140 
141 TEST(IntmathTest, mulSignedNarrow)
142 {
143  int8_t a = -0x80;
144  int8_t b = -0x7f;
145  int8_t hi;
146  int8_t low;
147  mulSigned<int8_t>(hi, low, a, b);
148  EXPECT_EQ(hi, 0x3f);
149  EXPECT_EQ(low, -0x80);
150 
151  a = 14;
152  b = -9;
153  mulSigned<int8_t>(hi, low, a, b);
154  EXPECT_EQ(hi, -0x01);
155  EXPECT_EQ(low, -0x7e);
156 
157  a = 0;
158  b = -0x55;
159  mulSigned<int8_t>(hi, low, a, b);
160  EXPECT_EQ(hi, 0);
161  EXPECT_EQ(low, 0);
162 }
163 
164 TEST(IntmathTest, mulUnsignedMid)
165 {
166  uint32_t a = 0xffffffffULL;
167  uint32_t b = 0x00000002ULL;
168  uint32_t hi;
169  uint32_t low;
170  mulUnsigned<uint32_t>(hi, low, a, b);
171  EXPECT_EQ(hi, 0x1);
172  EXPECT_EQ(low, 0xfffffffe);
173 
174  a = 68026386;
175  b = 5152;
176  mulUnsigned<uint32_t>(hi, low, a, b);
177  EXPECT_EQ(hi, 0x51);
178  EXPECT_EQ(low, 0x99c16a40);
179 
180  a = 0;
181  b = 0x55555555;
182  mulUnsigned<uint32_t>(hi, low, a, b);
183  EXPECT_EQ(hi, 0);
184  EXPECT_EQ(low, 0);
185 }
186 
187 TEST(IntmathTest, mulSignedMid)
188 {
189  int32_t a = -0x80000000;
190  int32_t b = -0x7fffffff;
191  int32_t hi;
192  int32_t low;
193  mulSigned<int32_t>(hi, low, a, b);
194  EXPECT_EQ(hi, 0x3fffffff);
195  EXPECT_EQ(low, -0x80000000);
196 
197  a = -68026386;
198  b = 5152;
199  mulSigned<int32_t>(hi, low, a, b);
200  EXPECT_EQ(hi, -0x52);
201  EXPECT_EQ(low, -0x99c16a40);
202 
203  a = 0;
204  b = -0x55555555;
205  mulSigned<int32_t>(hi, low, a, b);
206  EXPECT_EQ(hi, 0);
207  EXPECT_EQ(low, 0);
208 }
209 
210 TEST(IntmathTest, mulUnsignedWide)
211 {
212  uint64_t a = 0xffffffffffffffffULL;
213  uint64_t b = 0x0000000000000002ULL;
214  uint64_t hi;
215  uint64_t low;
216  mulUnsigned<uint64_t>(hi, low, a, b);
217  EXPECT_EQ(hi, 0x1);
218  EXPECT_EQ(low, 0xfffffffffffffffe);
219 
220  hi = 0;
221  low = 0;
222  mulUnsignedManual<uint64_t>(hi, low, a, b);
223  EXPECT_EQ(hi, 0x1);
224  EXPECT_EQ(low, 0xfffffffffffffffe);
225 
226  hi = 0;
227  low = 0;
228  std::tie(hi, low) = mulUnsigned<uint64_t>(a, b);
229  EXPECT_EQ(hi, 0x1);
230  EXPECT_EQ(low, 0xfffffffffffffffe);
231 
232  a = 0;
233  b = 0x5555555555555555;
234  mulUnsigned<uint64_t>(hi, low, a, b);
235  EXPECT_EQ(hi, 0);
236  EXPECT_EQ(low, 0);
237 }
238 
239 TEST(IntmathTest, mulSignedWide)
240 {
241  int64_t a = -0x8000000000000000;
242  int64_t b = -0x7fffffffffffffff;
243  int64_t hi;
244  int64_t low;
245  mulSigned<int64_t>(hi, low, a, b);
246  EXPECT_EQ(hi, 0x3fffffffffffffff);
247  EXPECT_EQ(low, -0x8000000000000000);
248 
249  hi = 0;
250  low = 0;
251  mulSignedManual<int64_t>(hi, low, a, b);
252  EXPECT_EQ(hi, 0x3fffffffffffffff);
253  EXPECT_EQ(low, -0x8000000000000000);
254 
255  hi = 0;
256  low = 0;
257  std::tie(hi, low) = mulSigned<int64_t>(a, b);
258  EXPECT_EQ(hi, 0x3fffffffffffffff);
259  EXPECT_EQ(low, -0x8000000000000000);
260 
261  a = 0;
262  b = -0x5555555555555555;
263  mulSigned<int64_t>(hi, low, a, b);
264  EXPECT_EQ(hi, 0);
265  EXPECT_EQ(low, 0);
266 }
267 
268 TEST(IntmathTest, roundUp)
269 {
270  EXPECT_EQ(4104, roundUp(4101, 4));
271  EXPECT_EQ(4112, roundUp(4105, 8));
272  EXPECT_EQ(4112, roundUp(4101, 16));
273  EXPECT_EQ(8192, roundUp(7991, 256));
274 }
275 
276 TEST(IntmathTest, roundDown)
277 {
278  EXPECT_EQ(4100, roundDown(4101, 4));
279  EXPECT_EQ(4104, roundDown(4105, 8));
280  EXPECT_EQ(4096, roundDown(4101, 16));
281  EXPECT_EQ(7936, roundDown(7991, 256));
282 }
283 
289 TEST(IntmathTest, Log2i)
290 {
291  int expected = 0;
292  for (int value = 1; value > 0; expected++, value <<= 1) {
293  EXPECT_EQ(expected, log2i(value));
294  }
295 
296  // Just as a sanity check for expected to point to the MSB
297  EXPECT_EQ(expected, sizeof(int) * 8 - 1);
298 }
299 
307 TEST(IntmathDeathTest, Log2iDeath)
308 {
309 
310 #ifdef NDEBUG
311  GTEST_SKIP() << "Skipping as assertions are "
312  "stripped out of fast builds";
313 #endif
314 
315  // 1) value = 0
316  EXPECT_DEATH({
317  const int value = 0;
318  log2i(value);
319  }, "value > 0.*failed");
320 
321  // 2) value < 0
322  EXPECT_DEATH({
323  const int value = -1;
324  log2i(value);
325  }, "value > 0.*failed");
326 
327  // 3) value is not a power of 2
328  EXPECT_DEATH({
329  const int value = 5;
330  log2i(value);
331  }, "isPowerOf2");
332 }
std::vector< SwitchingFiber * > expected({ &a, &b, &a, &a, &a, &b, &c, &a, &c, &c, &c })
static constexpr int log2i(int value)
Calculate the log2 of a power of 2 integer.
Definition: intmath.hh:295
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
Definition: intmath.hh:59
static constexpr int ceilLog2(const T &n)
Definition: intmath.hh:84
static constexpr bool isPowerOf2(const T &n)
Definition: intmath.hh:98
static constexpr T divCeil(const T &a, const U &b)
Definition: intmath.hh:110
static constexpr T roundDown(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:279
static constexpr T roundUp(const T &val, const U &align)
This function is used to align addresses in memory.
Definition: intmath.hh:260
TEST(IntmathTest, isPowerOf2)
Definition: intmath.test.cc:47
Bitfield< 7 > b
Definition: misc_types.hh:388
Bitfield< 8 > a
Definition: misc_types.hh:66
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....

Generated on Wed Dec 21 2022 10:22:29 for gem5 by doxygen 1.9.1