Path: blob/master/src/hotspot/share/utilities/count_trailing_zeros.hpp
40950 views
/*1* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_UTILITIES_COUNT_TRAILING_ZEROS_HPP25#define SHARE_UTILITIES_COUNT_TRAILING_ZEROS_HPP2627#include "metaprogramming/enableIf.hpp"28#include "utilities/debug.hpp"29#include "utilities/globalDefinitions.hpp"3031// unsigned count_trailing_zeros(T x)3233// Return the number of trailing zeros in x, e.g. the zero-based index34// of the least significant set bit in x.35// Precondition: x != 0.3637// We implement and support variants for 8, 16, 32 and 64 bit integral types.3839// Dispatch on toolchain to select implementation.4041/*****************************************************************************42* GCC and compatible (including Clang)43*****************************************************************************/44#if defined(TARGET_COMPILER_gcc)4546inline unsigned count_trailing_zeros_32(uint32_t x) {47return __builtin_ctz(x);48}4950inline unsigned count_trailing_zeros_64(uint64_t x) {51return __builtin_ctzll(x);52}5354/*****************************************************************************55* Microsoft Visual Studio56*****************************************************************************/57#elif defined(TARGET_COMPILER_visCPP)5859#include <intrin.h>6061#pragma intrinsic(_BitScanForward)62#ifdef _LP6463#pragma intrinsic(_BitScanForward64)64#endif6566inline unsigned count_trailing_zeros_32(uint32_t x) {67unsigned long index;68_BitScanForward(&index, x);69return index;70}7172inline unsigned count_trailing_zeros_64(uint64_t x) {73unsigned long index;74#ifdef _LP6475_BitScanForward64(&index, x);76#else77if (_BitScanForward(&index, static_cast<uint32_t>(x)) == 0) {78// no bit found? If so, try the upper dword. Otherwise index already contains the result79_BitScanForward(&index, static_cast<uint32_t>(x >> 32));80index += 32;81}82#endif83return index;84}8586/*****************************************************************************87* IBM XL C/C++88*****************************************************************************/89#elif defined(TARGET_COMPILER_xlc)9091#include <builtins.h>9293inline unsigned count_trailing_zeros_32(uint32_t x) {94return __cnttz4(x);95}9697inline unsigned count_trailing_zeros_64(uint64_t x) {98return __cnttz8(x);99}100101/*****************************************************************************102* Unknown toolchain103*****************************************************************************/104#else105#error Unknown TARGET_COMPILER106107#endif // Toolchain dispatch108109template<typename T,110ENABLE_IF(std::is_integral<T>::value),111ENABLE_IF(sizeof(T) <= sizeof(uint64_t))>112inline unsigned count_trailing_zeros(T x) {113assert(x != 0, "precondition");114return (sizeof(x) <= sizeof(uint32_t)) ?115count_trailing_zeros_32(static_cast<uint32_t>(x)) :116count_trailing_zeros_64(x);117}118119120#endif // SHARE_UTILITIES_COUNT_TRAILING_ZEROS_HPP121122123