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)37std::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