• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef ECMASCRIPT_BASE_BIT_HELPER_H
17 #define ECMASCRIPT_BASE_BIT_HELPER_H
18 
19 #include <cstdint>
20 #include <cstring>
21 #include <limits>
22 #include <type_traits>
23 
24 namespace panda::ecmascript::base {
25 template <class S, class R>
26 union Data {
27     S src;
28     R dst;
29 };
30 
31 template <typename T>
ReadBuffer(void ** buffer)32 inline T ReadBuffer(void **buffer)
33 {
34     T result = *(reinterpret_cast<T *>(*buffer));
35     *buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(*buffer) + result.offset_);
36     return result;
37 }
38 
ReadBuffer(void ** buffer)39 inline char *ReadBuffer(void **buffer)
40 {
41     auto result = reinterpret_cast<char *>(*buffer);
42     *buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(*buffer) + strlen(result) + 1);
43     return result;
44 }
45 
46 template <typename T>
ReadBufferInSize(void ** buffer)47 inline T *ReadBufferInSize(void **buffer)
48 {
49     T *result = reinterpret_cast<T *>(*buffer);
50     *buffer = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(*buffer) + result->Size());
51     return result;
52 }
53 
54 template <typename T>
CountLeadingZeros(T value)55 inline constexpr uint32_t CountLeadingZeros(T value)
56 {
57     constexpr size_t RADIX = 2;
58     static_assert(std::is_integral<T>::value, "T must be integral");
59     static_assert(std::is_unsigned<T>::value, "T must be unsigned");
60     static_assert(std::numeric_limits<T>::radix == RADIX, "Unexpected radix!");
61     static_assert(sizeof(T) == sizeof(uint64_t) || sizeof(T) <= sizeof(uint32_t), "Unsupported sizeof(T)");
62     if (value == 0) {
63         return sizeof(T) * 8;
64     }
65     if (sizeof(T) == sizeof(uint64_t)) {
66         return __builtin_clzll(static_cast<uint64_t>(value));
67     }
68     // 32 : 32 mean the bits of type T is less than 32
69     return __builtin_clz(static_cast<uint32_t>(value)) - (32 - std::numeric_limits<T>::digits);
70 }
71 
CountLeadingZeros32(uint32_t value)72 inline constexpr uint32_t CountLeadingZeros32(uint32_t value)
73 {
74     return CountLeadingZeros(value);
75 }
76 
CountLeadingZeros64(uint64_t value)77 inline constexpr uint32_t CountLeadingZeros64(uint64_t value)
78 {
79     return CountLeadingZeros(value);
80 }
81 
CountLeadingOnes32(uint32_t value)82 inline constexpr uint32_t CountLeadingOnes32(uint32_t value)
83 {
84     return CountLeadingZeros(~value);
85 }
86 
CountLeadingOnes64(uint64_t value)87 inline constexpr uint32_t CountLeadingOnes64(uint64_t value)
88 {
89     return CountLeadingZeros(~value);
90 }
91 
92 template <typename T>
CountTrailingZeros(T value)93 inline constexpr uint32_t CountTrailingZeros(T value)
94 {
95     constexpr size_t RADIX = 2;
96     static_assert(std::is_integral<T>::value, "T must be integral");
97     static_assert(std::is_unsigned<T>::value, "T must be unsigned");
98     static_assert(std::numeric_limits<T>::radix == RADIX, "Unexpected radix!");
99     static_assert(sizeof(T) == sizeof(uint64_t) || sizeof(T) <= sizeof(uint32_t), "Unsupported sizeof(T)");
100     if (value == 0) {
101         return sizeof(T) * 8;
102     }
103     if (sizeof(T) == sizeof(uint64_t)) {
104         return __builtin_ctzll(static_cast<uint64_t>(value));
105     }
106     return __builtin_ctz(static_cast<uint32_t>(value));
107 }
108 
CountTrailingZeros32(uint32_t value)109 inline constexpr unsigned CountTrailingZeros32(uint32_t value)
110 {
111     return CountTrailingZeros(value);
112 }
113 
CountTrailingZeros64(uint64_t value)114 inline constexpr unsigned CountTrailingZeros64(uint64_t value)
115 {
116     return CountTrailingZeros(value);
117 }
118 
CountTrailingOnes32(uint32_t value)119 inline constexpr unsigned CountTrailingOnes32(uint32_t value)
120 {
121     return CountTrailingZeros(~value);
122 }
123 
CountTrailingOnes64(uint64_t value)124 inline constexpr unsigned CountTrailingOnes64(uint64_t value)
125 {
126     return CountTrailingZeros(~value);
127 }
128 
129 /// isMask_64 - This function returns true if the argument is a non-empty
130 /// sequence of ones starting at the least significant bit with the remainder
131 /// zero (64 bit version).
IsMask_64(uint64_t Value)132 constexpr inline bool IsMask_64(uint64_t Value)
133 {
134     return Value && ((Value + 1) & Value) == 0;
135 }
136 
137 /// isShiftedMask_64 - This function returns true if the argument contains a
138 /// non-empty sequence of ones with the remainder zero (64 bit version.)
IsShiftedMask_64(uint64_t Value)139 constexpr inline bool IsShiftedMask_64(uint64_t Value)
140 {
141     return Value && IsMask_64((Value - 1) | Value);
142 }
143 
144 template <typename T>
RoundUp(T x,size_t n)145 constexpr T RoundUp(T x, size_t n)
146 {
147     static_assert(std::is_integral<T>::value, "T must be integral");
148     return (static_cast<size_t>(x) + n - 1U) & (-n);
149 }
150 
151 template <class To, class From>
bit_cast(const From & src)152 inline To bit_cast(const From &src) noexcept  // NOLINT(readability-identifier-naming)
153 {
154     static_assert(sizeof(To) == sizeof(From), "size of the types must be equal");
155     // The use of security functions 'memcpy_s' here will have a greater impact on performance
156     Data<From, To> data_;
157     data_.src = src;
158     return data_.dst;
159 }
160 
161 template <typename T>
BitNumbers()162 inline constexpr uint32_t BitNumbers()
163 {
164     constexpr int BIT_NUMBER_OF_CHAR = 8;
165     return sizeof(T) * BIT_NUMBER_OF_CHAR;
166 }
167 }  // panda::ecmascript::base
168 #endif
169