1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "utils/regmask.h"
16
17 #include <gtest/gtest.h>
18 #include <bitset>
19
20 namespace panda::test {
21
22 using BitsetType = std::bitset<RegMask::Size()>;
23
CompareWithBitset(RegMask mask,BitsetType base)24 void CompareWithBitset(RegMask mask, BitsetType base)
25 {
26 ASSERT_EQ(mask.Count(), base.count());
27 if (base.any()) {
28 ASSERT_EQ(mask.GetMinRegister(), static_cast<uint32_t>(Ctz(base.to_ulong())));
29 ASSERT_EQ(mask.GetMaxRegister(), base.size() - Clz(static_cast<RegMask::ValueType>(base.to_ulong())) - 1);
30 }
31 ASSERT_EQ(mask.Size(), base.size());
32 ASSERT_EQ(mask.Any(), base.any());
33 ASSERT_EQ(mask.None(), base.none());
34 for (size_t i = 0; i < base.size(); i++) {
35 ASSERT_EQ(mask.Test(i), base.test(i));
36 ASSERT_EQ(mask[i], base[i]);
37 }
38 }
39
TestRegMask(RegMask::ValueType value)40 void TestRegMask(RegMask::ValueType value)
41 {
42 RegMask mask(value);
43 BitsetType base(value);
44 CompareWithBitset(mask, base);
45 for (size_t i = 0; i < base.size(); i++) {
46 mask.set(i);
47 base.set(i);
48 CompareWithBitset(mask, base);
49 mask.reset(i);
50 base.reset(i);
51 CompareWithBitset(mask, base);
52 }
53 mask.Set();
54 base.set();
55 CompareWithBitset(mask, base);
56 mask.Reset();
57 base.reset();
58 CompareWithBitset(mask, base);
59 }
60
TestDistance(RegMask mask,size_t bit,size_t bits_before,size_t bits_after)61 void TestDistance(RegMask mask, size_t bit, size_t bits_before, size_t bits_after)
62 {
63 ASSERT_EQ(mask.GetDistanceFromTail(bit), bits_before);
64 ASSERT_EQ(mask.GetDistanceFromHead(bit), bits_after);
65 }
66
67 HWTEST(RegMask, Base, testing::ext::TestSize.Level0)
68 {
69 TestRegMask(MakeMask(0, 3, 2, 17, 25, 31));
70 TestRegMask(MakeMask(1, 4, 8, 3, 24, 28, 30));
71 TestRegMask(MakeMaskByExcluding(32, 0));
72 TestRegMask(MakeMaskByExcluding(32, 31));
73 TestRegMask(MakeMaskByExcluding(32, 0, 31));
74 TestRegMask(MakeMaskByExcluding(32, 0, 15, 31));
75 TestRegMask(0U);
76 TestRegMask(~0U);
77
78 RegMask mask(MakeMask(0, 2, 3, 17, 25, 31));
79 TestDistance(mask, 0, 0, 5);
80 TestDistance(mask, 1, 1, 5);
81 TestDistance(mask, 2, 1, 4);
82 TestDistance(mask, 3, 2, 3);
83 TestDistance(mask, 4, 3, 3);
84 TestDistance(mask, 17, 3, 2);
85 TestDistance(mask, 18, 4, 2);
86 TestDistance(mask, 31, 5, 0);
87 }
88
89 HWTEST(RegMask, SetAndDumpTest, testing::ext::TestSize.Level0)
90 {
91 RegMask mask(MakeMask(1, 2, 3));
92 ASSERT_EQ(mask.GetValue(), 14U);
93
94 mask.Set(1U, false);
95 ASSERT_EQ(mask.GetValue(), 12U);
96
97 mask.Set(5U, true);
98 ASSERT_EQ(mask.GetValue(), 44U);
99 }
100
101 } // namespace panda::test