1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef BERBERIS_INTRINSICS_INTRINSICS_BITMANIP_IMPL_H_
18 #define BERBERIS_INTRINSICS_INTRINSICS_BITMANIP_IMPL_H_
19 
20 #include <cstdint>
21 
22 namespace berberis::intrinsics {
23 
24 // TODO(b/260725458): stop using __builtin_popcount after C++20 would become available.
25 template <>
26 inline std::tuple<int64_t> Cpop<int32_t, kUseCppImplementation>(int32_t src) {
27   return {__builtin_popcount(src)};
28 }
29 
30 // TODO(b/260725458): stop using __builtin_popcountll after C++20 would become available.
31 template <>
32 inline std::tuple<int64_t> Cpop<int64_t, kUseCppImplementation>(int64_t src) {
33   return {__builtin_popcountll(src)};
34 }
35 
36 template <typename ElementType>
Brev8(ElementType arg)37 std::tuple<ElementType> Brev8(ElementType arg) {
38   constexpr unsigned long ls1 = 0x5555'5555'5555'5555;
39   constexpr unsigned long rs1 = 0xAAAA'AAAA'AAAA'AAAA;
40   constexpr unsigned long ls2 = 0x3333'3333'3333'3333;
41   constexpr unsigned long rs2 = 0xCCCC'CCCC'CCCC'CCCC;
42   constexpr unsigned long ls4 = 0x0F0F'0F0F'0F0F'0F0F;
43   constexpr unsigned long rs4 = 0xF0F0'F0F0'F0F0'F0F0;
44   auto tmp_arg = static_cast<typename ElementType::BaseType>(arg);
45 
46   tmp_arg = ((tmp_arg & ls1) << 1) | ((tmp_arg & rs1) >> 1);
47   tmp_arg = ((tmp_arg & ls2) << 2) | ((tmp_arg & rs2) >> 2);
48   tmp_arg = ((tmp_arg & ls4) << 4) | ((tmp_arg & rs4) >> 4);
49 
50   return {ElementType{tmp_arg}};
51 }
52 
53 }  // namespace berberis::intrinsics
54 
55 #endif  // BERBERIS_INTRINSICS_INTRINSICS_BITMANIP_IMPL_H_
56