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