1330d8983SJohannes Doerfert //===-- Shared/Utils.h - Target independent OpenMP target RTL -- C++ ------===// 2330d8983SJohannes Doerfert // 3330d8983SJohannes Doerfert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4330d8983SJohannes Doerfert // See https://llvm.org/LICENSE.txt for license information. 5330d8983SJohannes Doerfert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6330d8983SJohannes Doerfert // 7330d8983SJohannes Doerfert //===----------------------------------------------------------------------===// 8330d8983SJohannes Doerfert // 908533a3eSJohannes Doerfert // Routines and classes used to provide useful functionalities for the host and 1008533a3eSJohannes Doerfert // the device. 11330d8983SJohannes Doerfert // 12330d8983SJohannes Doerfert //===----------------------------------------------------------------------===// 13330d8983SJohannes Doerfert 14330d8983SJohannes Doerfert #ifndef OMPTARGET_SHARED_UTILS_H 15330d8983SJohannes Doerfert #define OMPTARGET_SHARED_UTILS_H 16330d8983SJohannes Doerfert 17*c3ac3fe8SJoseph Huber #include <stdint.h> 18330d8983SJohannes Doerfert 1908533a3eSJohannes Doerfert namespace utils { 20330d8983SJohannes Doerfert 21330d8983SJohannes Doerfert /// Return the difference (in bytes) between \p Begin and \p End. 22330d8983SJohannes Doerfert template <typename Ty = char> 2308533a3eSJohannes Doerfert auto getPtrDiff(const void *End, const void *Begin) { 24330d8983SJohannes Doerfert return reinterpret_cast<const Ty *>(End) - 25330d8983SJohannes Doerfert reinterpret_cast<const Ty *>(Begin); 26330d8983SJohannes Doerfert } 27330d8983SJohannes Doerfert 28330d8983SJohannes Doerfert /// Return \p Ptr advanced by \p Offset bytes. 2908533a3eSJohannes Doerfert template <typename Ty1, typename Ty2> Ty1 *advancePtr(Ty1 *Ptr, Ty2 Offset) { 3008533a3eSJohannes Doerfert return (Ty1 *)(const_cast<char *>((const char *)(Ptr)) + Offset); 31330d8983SJohannes Doerfert } 32330d8983SJohannes Doerfert 3308533a3eSJohannes Doerfert /// Return \p V aligned "upwards" according to \p Align. 3408533a3eSJohannes Doerfert template <typename Ty1, typename Ty2> inline Ty1 alignPtr(Ty1 V, Ty2 Align) { 3508533a3eSJohannes Doerfert return reinterpret_cast<Ty1>(((uintptr_t(V) + Align - 1) / Align) * Align); 3608533a3eSJohannes Doerfert } 3708533a3eSJohannes Doerfert /// Return \p V aligned "downwards" according to \p Align. 3808533a3eSJohannes Doerfert template <typename Ty1, typename Ty2> inline Ty1 alignDown(Ty1 V, Ty2 Align) { 3908533a3eSJohannes Doerfert return V - V % Align; 40330d8983SJohannes Doerfert } 41330d8983SJohannes Doerfert 42330d8983SJohannes Doerfert /// Round up \p V to a \p Boundary. 43330d8983SJohannes Doerfert template <typename Ty> inline Ty roundUp(Ty V, Ty Boundary) { 4408533a3eSJohannes Doerfert return alignPtr(V, Boundary); 45330d8983SJohannes Doerfert } 46330d8983SJohannes Doerfert 4708533a3eSJohannes Doerfert /// Return the first bit set in \p V. 4808533a3eSJohannes Doerfert inline uint32_t ffs(uint32_t V) { 4908533a3eSJohannes Doerfert static_assert(sizeof(int) == sizeof(uint32_t), "type size mismatch"); 5008533a3eSJohannes Doerfert return __builtin_ffs(V); 5108533a3eSJohannes Doerfert } 5208533a3eSJohannes Doerfert 5308533a3eSJohannes Doerfert /// Return the first bit set in \p V. 5408533a3eSJohannes Doerfert inline uint32_t ffs(uint64_t V) { 5508533a3eSJohannes Doerfert static_assert(sizeof(long) == sizeof(uint64_t), "type size mismatch"); 5608533a3eSJohannes Doerfert return __builtin_ffsl(V); 5708533a3eSJohannes Doerfert } 5808533a3eSJohannes Doerfert 5908533a3eSJohannes Doerfert /// Return the number of bits set in \p V. 6008533a3eSJohannes Doerfert inline uint32_t popc(uint32_t V) { 6108533a3eSJohannes Doerfert static_assert(sizeof(int) == sizeof(uint32_t), "type size mismatch"); 6208533a3eSJohannes Doerfert return __builtin_popcount(V); 6308533a3eSJohannes Doerfert } 6408533a3eSJohannes Doerfert 6508533a3eSJohannes Doerfert /// Return the number of bits set in \p V. 6608533a3eSJohannes Doerfert inline uint32_t popc(uint64_t V) { 6708533a3eSJohannes Doerfert static_assert(sizeof(long) == sizeof(uint64_t), "type size mismatch"); 6808533a3eSJohannes Doerfert return __builtin_popcountl(V); 6908533a3eSJohannes Doerfert } 7008533a3eSJohannes Doerfert 7108533a3eSJohannes Doerfert } // namespace utils 72330d8983SJohannes Doerfert 73330d8983SJohannes Doerfert #endif // OMPTARGET_SHARED_UTILS_H 74