1/*
2 * Copyright (c) 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
16#include "ecmascript/base/bit_helper.h"
17#include "ecmascript/tests/test_helper.h"
18
19using namespace panda::ecmascript;
20using namespace panda::ecmascript::base;
21
22namespace panda::test {
23class BitHelperTest : public BaseTestWithScope<false> {
24protected:
25    template <class To, class From>
26    inline To MemoryCast(const From &src) noexcept
27    {
28        static_assert(sizeof(To) == sizeof(From), "size of the types must be equal");
29        To dst;
30        if (memcpy_s(&dst, sizeof(To), &src, sizeof(From)) != EOK) {
31            LOG_FULL(FATAL) << "memcpy_s failed";
32            UNREACHABLE();
33        }
34        return dst;
35    }
36};
37
38HWTEST_F_L0(BitHelperTest, CountLeadingZeros_CountTrailingZeros)
39{
40    uint8_t uint8MaxValue = std::numeric_limits<uint8_t>::max();
41    uint8_t uint8MinValue = std::numeric_limits<uint8_t>::min();
42    EXPECT_EQ(CountLeadingZeros<uint8_t>(uint8MaxValue), 0U);
43    EXPECT_EQ(CountLeadingZeros<uint8_t>(uint8MinValue), 8U);
44    EXPECT_EQ(CountTrailingZeros<uint8_t>(uint8MaxValue), 0U);
45    EXPECT_EQ(CountTrailingZeros<uint8_t>(uint8MinValue), 8U);
46
47    uint16_t uint16MaxValue = std::numeric_limits<uint16_t>::max();
48    uint16_t uint16MinValue = std::numeric_limits<uint16_t>::min();
49    EXPECT_EQ(CountLeadingZeros<uint16_t>(uint16MaxValue), 0U);
50    EXPECT_EQ(CountLeadingZeros<uint16_t>(uint16MinValue), 16U);
51    EXPECT_EQ(CountTrailingZeros<uint16_t>(uint16MaxValue), 0U);
52    EXPECT_EQ(CountTrailingZeros<uint16_t>(uint16MinValue), 16U);
53
54    uint32_t uint32MaxValue = std::numeric_limits<uint32_t>::max();
55    uint32_t uint32MinValue = std::numeric_limits<uint32_t>::min();
56    EXPECT_EQ(CountLeadingZeros<uint32_t>(uint32MaxValue), 0U);
57    EXPECT_EQ(CountLeadingZeros<uint32_t>(uint32MinValue), 32U);
58    EXPECT_EQ(CountTrailingZeros<uint32_t>(uint32MaxValue), 0U);
59    EXPECT_EQ(CountTrailingZeros<uint32_t>(uint32MinValue), 32U);
60
61    uint64_t uint64MaxValue = std::numeric_limits<uint64_t>::max();
62    uint64_t uint64MinValue = std::numeric_limits<uint64_t>::min();
63    EXPECT_EQ(CountLeadingZeros<uint64_t>(uint64MaxValue), 0U);
64    EXPECT_EQ(CountLeadingZeros<uint64_t>(uint64MinValue), 64U);
65    EXPECT_EQ(CountTrailingZeros<uint64_t>(uint64MaxValue), 0U);
66    EXPECT_EQ(CountTrailingZeros<uint64_t>(uint64MinValue), 64U);
67}
68
69HWTEST_F_L0(BitHelperTest, CountLeadingZeros32_CountLeadingOnes32)
70{
71    uint32_t uint32MaxValue = std::numeric_limits<uint32_t>::max();
72    uint32_t uint32CommonValue1 = std::numeric_limits<uint32_t>::max() >> 1;
73    uint32_t uint32CommonValue2 = std::numeric_limits<uint32_t>::max() >> 31; // 31 : right shift digit
74    uint32_t uint32MinValue = std::numeric_limits<uint32_t>::min();
75    EXPECT_EQ(CountLeadingZeros32(uint32MaxValue), 0U);
76    EXPECT_EQ(CountLeadingZeros32(uint32CommonValue1), 1U);
77    EXPECT_EQ(CountLeadingZeros32(uint32CommonValue2), 31U);
78    EXPECT_EQ(CountLeadingZeros32(uint32MinValue), 32U);
79    EXPECT_EQ(CountLeadingOnes32(uint32MaxValue), 32U);
80    EXPECT_EQ(CountLeadingOnes32(uint32CommonValue1), 0U);
81    EXPECT_EQ(CountLeadingOnes32(uint32CommonValue2), 0U);
82    EXPECT_EQ(CountLeadingOnes32(uint32MinValue), 0U);
83}
84
85HWTEST_F_L0(BitHelperTest, CountLeadingZeros64_CountLeadingOnes64)
86{
87    uint64_t uint64MaxValue = std::numeric_limits<uint64_t>::max();
88    uint64_t uint64CommonValue1 = std::numeric_limits<uint64_t>::max() >> 1;
89    uint64_t uint64CommonValue2 = std::numeric_limits<uint64_t>::max() >> 63; // 63 : right shift digit
90    uint64_t uint64MinValue = std::numeric_limits<uint64_t>::min();
91    EXPECT_EQ(CountLeadingZeros64(uint64MaxValue), 0U);
92    EXPECT_EQ(CountLeadingZeros64(uint64CommonValue1), 1U);
93    EXPECT_EQ(CountLeadingZeros64(uint64CommonValue2), 63U);
94    EXPECT_EQ(CountLeadingZeros64(uint64MinValue), 64U);
95    EXPECT_EQ(CountLeadingOnes64(uint64MaxValue), 64U);
96    EXPECT_EQ(CountLeadingOnes64(uint64CommonValue1), 0U);
97    EXPECT_EQ(CountLeadingOnes64(uint64CommonValue2), 0U);
98    EXPECT_EQ(CountLeadingOnes64(uint64MinValue), 0U);
99}
100
101HWTEST_F_L0(BitHelperTest, bit_cast)
102{
103    int8_t int8Value = -128;
104    uint8_t uint8Value = 255;
105    char char8Value = 127;
106    EXPECT_EQ(bit_cast<uint8_t>(int8Value), MemoryCast<uint8_t>(int8Value));
107    EXPECT_EQ(bit_cast<char>(int8Value), MemoryCast<char>(int8Value));
108    EXPECT_EQ(bit_cast<int8_t>(uint8Value), MemoryCast<int8_t>(uint8Value));
109    EXPECT_EQ(bit_cast<char>(uint8Value), MemoryCast<char>(uint8Value));
110    EXPECT_EQ(bit_cast<int8_t>(char8Value), MemoryCast<int8_t>(char8Value));
111    EXPECT_EQ(bit_cast<uint8_t>(char8Value), MemoryCast<uint8_t>(char8Value));
112
113    int16_t int16Value = -32768;
114    uint16_t uint16Value = 65535;
115    char16_t char16Value = 32767;
116    EXPECT_EQ(bit_cast<uint16_t>(int16Value), MemoryCast<uint16_t>(int16Value));
117    EXPECT_EQ(bit_cast<char16_t>(int16Value), MemoryCast<char16_t>(int16Value));
118    EXPECT_EQ(bit_cast<int16_t>(uint16Value), MemoryCast<int16_t>(uint16Value));
119    EXPECT_EQ(bit_cast<char16_t>(uint16Value), MemoryCast<char16_t>(uint16Value));
120    EXPECT_EQ(bit_cast<int16_t>(char16Value), MemoryCast<int16_t>(char16Value));
121    EXPECT_EQ(bit_cast<uint16_t>(char16Value), MemoryCast<uint16_t>(char16Value));
122
123    int32_t int32Value = -2147483648;
124    uint32_t uint32Value = 2147483648;
125    float floatValue = -13.569243f;
126    char32_t char32Value = 2147483648;
127    EXPECT_EQ(bit_cast<uint32_t>(int32Value), MemoryCast<uint32_t>(int32Value));
128    EXPECT_EQ(bit_cast<float>(int32Value), MemoryCast<float>(int32Value));
129    EXPECT_EQ(bit_cast<char32_t>(int32Value), MemoryCast<char32_t>(int32Value));
130    EXPECT_EQ(bit_cast<int32_t>(uint32Value), MemoryCast<int32_t>(uint32Value));
131    EXPECT_EQ(bit_cast<float>(uint32Value), MemoryCast<float>(uint32Value));
132    EXPECT_EQ(bit_cast<char32_t>(uint32Value), MemoryCast<char32_t>(uint32Value));
133    EXPECT_EQ(bit_cast<int32_t>(floatValue), MemoryCast<int32_t>(floatValue));
134    EXPECT_EQ(bit_cast<uint32_t>(floatValue), MemoryCast<uint32_t>(floatValue));
135    EXPECT_EQ(bit_cast<char32_t>(floatValue), MemoryCast<char32_t>(floatValue));
136    EXPECT_EQ(bit_cast<int32_t>(char32Value), MemoryCast<int32_t>(char32Value));
137    EXPECT_EQ(bit_cast<uint32_t>(char32Value), MemoryCast<uint32_t>(char32Value));
138    EXPECT_EQ(bit_cast<float>(char32Value), MemoryCast<float>(char32Value));
139
140    int64_t int64Value = -9223372036854775807LL;
141    uint64_t uint64Value = 9223372036854775808ULL;
142    double doubleValue = -257.93458301390463;
143    EXPECT_EQ(bit_cast<uint64_t>(int64Value), MemoryCast<uint64_t>(int64Value));
144    EXPECT_EQ(bit_cast<double>(int64Value), MemoryCast<double>(int64Value));
145    EXPECT_EQ(bit_cast<int64_t>(uint64Value), MemoryCast<int64_t>(uint64Value));
146    EXPECT_EQ(bit_cast<double>(uint64Value), MemoryCast<double>(uint64Value));
147    EXPECT_EQ(bit_cast<int64_t>(doubleValue), MemoryCast<int64_t>(doubleValue));
148    EXPECT_EQ(bit_cast<uint64_t>(doubleValue), MemoryCast<uint64_t>(doubleValue));
149}
150}  // namespace panda::test
151