1*523fa7a6SAndroid Build Coastguard Worker /* 2*523fa7a6SAndroid Build Coastguard Worker * Copyright (c) Meta Platforms, Inc. and affiliates. 3*523fa7a6SAndroid Build Coastguard Worker * All rights reserved. 4*523fa7a6SAndroid Build Coastguard Worker * 5*523fa7a6SAndroid Build Coastguard Worker * This source code is licensed under the BSD-style license found in the 6*523fa7a6SAndroid Build Coastguard Worker * LICENSE file in the root directory of this source tree. 7*523fa7a6SAndroid Build Coastguard Worker */ 8*523fa7a6SAndroid Build Coastguard Worker 9*523fa7a6SAndroid Build Coastguard Worker //===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===// 10*523fa7a6SAndroid Build Coastguard Worker // 11*523fa7a6SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 12*523fa7a6SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information. 13*523fa7a6SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 14*523fa7a6SAndroid Build Coastguard Worker // 15*523fa7a6SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 16*523fa7a6SAndroid Build Coastguard Worker // 17*523fa7a6SAndroid Build Coastguard Worker // This file contains some functions that are useful for math stuff. 18*523fa7a6SAndroid Build Coastguard Worker // 19*523fa7a6SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 20*523fa7a6SAndroid Build Coastguard Worker 21*523fa7a6SAndroid Build Coastguard Worker #pragma once 22*523fa7a6SAndroid Build Coastguard Worker 23*523fa7a6SAndroid Build Coastguard Worker #include <algorithm> 24*523fa7a6SAndroid Build Coastguard Worker #include <cassert> 25*523fa7a6SAndroid Build Coastguard Worker #include <climits> 26*523fa7a6SAndroid Build Coastguard Worker #include <cmath> 27*523fa7a6SAndroid Build Coastguard Worker #include <cstdint> 28*523fa7a6SAndroid Build Coastguard Worker #include <cstring> 29*523fa7a6SAndroid Build Coastguard Worker #include <limits> 30*523fa7a6SAndroid Build Coastguard Worker #include <type_traits> 31*523fa7a6SAndroid Build Coastguard Worker 32*523fa7a6SAndroid Build Coastguard Worker #ifdef __ANDROID_NDK__ 33*523fa7a6SAndroid Build Coastguard Worker #include <android/api-level.h> 34*523fa7a6SAndroid Build Coastguard Worker #endif 35*523fa7a6SAndroid Build Coastguard Worker 36*523fa7a6SAndroid Build Coastguard Worker #ifndef __has_builtin 37*523fa7a6SAndroid Build Coastguard Worker #define __has_builtin(x) 0 38*523fa7a6SAndroid Build Coastguard Worker #endif 39*523fa7a6SAndroid Build Coastguard Worker 40*523fa7a6SAndroid Build Coastguard Worker #ifndef LLVM_GNUC_PREREQ 41*523fa7a6SAndroid Build Coastguard Worker #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) 42*523fa7a6SAndroid Build Coastguard Worker #define LLVM_GNUC_PREREQ(maj, min, patch) \ 43*523fa7a6SAndroid Build Coastguard Worker ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \ 44*523fa7a6SAndroid Build Coastguard Worker ((maj) << 20) + ((min) << 10) + (patch)) 45*523fa7a6SAndroid Build Coastguard Worker #elif defined(__GNUC__) && defined(__GNUC_MINOR__) 46*523fa7a6SAndroid Build Coastguard Worker #define LLVM_GNUC_PREREQ(maj, min, patch) \ 47*523fa7a6SAndroid Build Coastguard Worker ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10)) 48*523fa7a6SAndroid Build Coastguard Worker #else 49*523fa7a6SAndroid Build Coastguard Worker #define LLVM_GNUC_PREREQ(maj, min, patch) 0 50*523fa7a6SAndroid Build Coastguard Worker #endif 51*523fa7a6SAndroid Build Coastguard Worker #endif 52*523fa7a6SAndroid Build Coastguard Worker 53*523fa7a6SAndroid Build Coastguard Worker #ifdef _MSC_VER 54*523fa7a6SAndroid Build Coastguard Worker // Declare these intrinsics manually rather including intrin.h. It's very 55*523fa7a6SAndroid Build Coastguard Worker // expensive, and MathExtras.h is popular. 56*523fa7a6SAndroid Build Coastguard Worker // #include <intrin.h> 57*523fa7a6SAndroid Build Coastguard Worker extern "C" { 58*523fa7a6SAndroid Build Coastguard Worker unsigned char _BitScanForward(unsigned long* _Index, unsigned long _Mask); 59*523fa7a6SAndroid Build Coastguard Worker unsigned char _BitScanForward64(unsigned long* _Index, unsigned __int64 _Mask); 60*523fa7a6SAndroid Build Coastguard Worker unsigned char _BitScanReverse(unsigned long* _Index, unsigned long _Mask); 61*523fa7a6SAndroid Build Coastguard Worker unsigned char _BitScanReverse64(unsigned long* _Index, unsigned __int64 _Mask); 62*523fa7a6SAndroid Build Coastguard Worker } 63*523fa7a6SAndroid Build Coastguard Worker #endif 64*523fa7a6SAndroid Build Coastguard Worker 65*523fa7a6SAndroid Build Coastguard Worker namespace executorch { 66*523fa7a6SAndroid Build Coastguard Worker namespace llvm { 67*523fa7a6SAndroid Build Coastguard Worker /// The behavior an operation has on an input of 0. 68*523fa7a6SAndroid Build Coastguard Worker enum ZeroBehavior { 69*523fa7a6SAndroid Build Coastguard Worker /// The returned value is undefined. 70*523fa7a6SAndroid Build Coastguard Worker ZB_Undefined, 71*523fa7a6SAndroid Build Coastguard Worker /// The returned value is numeric_limits<T>::max() 72*523fa7a6SAndroid Build Coastguard Worker ZB_Max, 73*523fa7a6SAndroid Build Coastguard Worker /// The returned value is numeric_limits<T>::digits 74*523fa7a6SAndroid Build Coastguard Worker ZB_Width 75*523fa7a6SAndroid Build Coastguard Worker }; 76*523fa7a6SAndroid Build Coastguard Worker 77*523fa7a6SAndroid Build Coastguard Worker namespace detail { 78*523fa7a6SAndroid Build Coastguard Worker template <typename T, std::size_t SizeOfT> 79*523fa7a6SAndroid Build Coastguard Worker struct TrailingZerosCounter { countTrailingZerosCounter80*523fa7a6SAndroid Build Coastguard Worker static std::size_t count(T Val, ZeroBehavior) { 81*523fa7a6SAndroid Build Coastguard Worker if (!Val) 82*523fa7a6SAndroid Build Coastguard Worker return std::numeric_limits<T>::digits; 83*523fa7a6SAndroid Build Coastguard Worker if (Val & 0x1) 84*523fa7a6SAndroid Build Coastguard Worker return 0; 85*523fa7a6SAndroid Build Coastguard Worker 86*523fa7a6SAndroid Build Coastguard Worker // Bisection method. 87*523fa7a6SAndroid Build Coastguard Worker std::size_t ZeroBits = 0; 88*523fa7a6SAndroid Build Coastguard Worker T Shift = std::numeric_limits<T>::digits >> 1; 89*523fa7a6SAndroid Build Coastguard Worker T Mask = std::numeric_limits<T>::max() >> Shift; 90*523fa7a6SAndroid Build Coastguard Worker while (Shift) { 91*523fa7a6SAndroid Build Coastguard Worker if ((Val & Mask) == 0) { 92*523fa7a6SAndroid Build Coastguard Worker Val >>= Shift; 93*523fa7a6SAndroid Build Coastguard Worker ZeroBits |= Shift; 94*523fa7a6SAndroid Build Coastguard Worker } 95*523fa7a6SAndroid Build Coastguard Worker Shift >>= 1; 96*523fa7a6SAndroid Build Coastguard Worker Mask >>= Shift; 97*523fa7a6SAndroid Build Coastguard Worker } 98*523fa7a6SAndroid Build Coastguard Worker return ZeroBits; 99*523fa7a6SAndroid Build Coastguard Worker } 100*523fa7a6SAndroid Build Coastguard Worker }; 101*523fa7a6SAndroid Build Coastguard Worker 102*523fa7a6SAndroid Build Coastguard Worker #if (defined(__GNUC__) && __GNUC__ >= 4) || defined(_MSC_VER) 103*523fa7a6SAndroid Build Coastguard Worker template <typename T> 104*523fa7a6SAndroid Build Coastguard Worker struct TrailingZerosCounter<T, 4> { 105*523fa7a6SAndroid Build Coastguard Worker static std::size_t count(T Val, ZeroBehavior ZB) { 106*523fa7a6SAndroid Build Coastguard Worker if (ZB != ZB_Undefined && Val == 0) 107*523fa7a6SAndroid Build Coastguard Worker return 32; 108*523fa7a6SAndroid Build Coastguard Worker 109*523fa7a6SAndroid Build Coastguard Worker #if __has_builtin(__builtin_ctz) || LLVM_GNUC_PREREQ(4, 0, 0) 110*523fa7a6SAndroid Build Coastguard Worker return __builtin_ctz(Val); 111*523fa7a6SAndroid Build Coastguard Worker #elif defined(_MSC_VER) 112*523fa7a6SAndroid Build Coastguard Worker unsigned long Index; 113*523fa7a6SAndroid Build Coastguard Worker _BitScanForward(&Index, Val); 114*523fa7a6SAndroid Build Coastguard Worker return Index; 115*523fa7a6SAndroid Build Coastguard Worker #endif 116*523fa7a6SAndroid Build Coastguard Worker } 117*523fa7a6SAndroid Build Coastguard Worker }; 118*523fa7a6SAndroid Build Coastguard Worker 119*523fa7a6SAndroid Build Coastguard Worker #if !defined(_MSC_VER) || defined(_M_X64) 120*523fa7a6SAndroid Build Coastguard Worker template <typename T> 121*523fa7a6SAndroid Build Coastguard Worker struct TrailingZerosCounter<T, 8> { 122*523fa7a6SAndroid Build Coastguard Worker static std::size_t count(T Val, ZeroBehavior ZB) { 123*523fa7a6SAndroid Build Coastguard Worker if (ZB != ZB_Undefined && Val == 0) 124*523fa7a6SAndroid Build Coastguard Worker return 64; 125*523fa7a6SAndroid Build Coastguard Worker 126*523fa7a6SAndroid Build Coastguard Worker #if __has_builtin(__builtin_ctzll) || LLVM_GNUC_PREREQ(4, 0, 0) 127*523fa7a6SAndroid Build Coastguard Worker return __builtin_ctzll(Val); 128*523fa7a6SAndroid Build Coastguard Worker #elif defined(_MSC_VER) 129*523fa7a6SAndroid Build Coastguard Worker unsigned long Index; 130*523fa7a6SAndroid Build Coastguard Worker _BitScanForward64(&Index, Val); 131*523fa7a6SAndroid Build Coastguard Worker return Index; 132*523fa7a6SAndroid Build Coastguard Worker #endif 133*523fa7a6SAndroid Build Coastguard Worker } 134*523fa7a6SAndroid Build Coastguard Worker }; 135*523fa7a6SAndroid Build Coastguard Worker #endif 136*523fa7a6SAndroid Build Coastguard Worker #endif 137*523fa7a6SAndroid Build Coastguard Worker } // namespace detail 138*523fa7a6SAndroid Build Coastguard Worker 139*523fa7a6SAndroid Build Coastguard Worker /// Count number of 0's from the least significant bit to the most 140*523fa7a6SAndroid Build Coastguard Worker /// stopping at the first 1. 141*523fa7a6SAndroid Build Coastguard Worker /// 142*523fa7a6SAndroid Build Coastguard Worker /// Only unsigned integral types are allowed. 143*523fa7a6SAndroid Build Coastguard Worker /// 144*523fa7a6SAndroid Build Coastguard Worker /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are 145*523fa7a6SAndroid Build Coastguard Worker /// valid arguments. 146*523fa7a6SAndroid Build Coastguard Worker template <typename T> 147*523fa7a6SAndroid Build Coastguard Worker std::size_t countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) { 148*523fa7a6SAndroid Build Coastguard Worker static_assert( 149*523fa7a6SAndroid Build Coastguard Worker std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, 150*523fa7a6SAndroid Build Coastguard Worker "Only unsigned integral types are allowed."); 151*523fa7a6SAndroid Build Coastguard Worker return llvm::detail::TrailingZerosCounter<T, sizeof(T)>::count(Val, ZB); 152*523fa7a6SAndroid Build Coastguard Worker } 153*523fa7a6SAndroid Build Coastguard Worker 154*523fa7a6SAndroid Build Coastguard Worker namespace detail { 155*523fa7a6SAndroid Build Coastguard Worker template <typename T, std::size_t SizeOfT> 156*523fa7a6SAndroid Build Coastguard Worker struct LeadingZerosCounter { 157*523fa7a6SAndroid Build Coastguard Worker static std::size_t count(T Val, ZeroBehavior) { 158*523fa7a6SAndroid Build Coastguard Worker if (!Val) 159*523fa7a6SAndroid Build Coastguard Worker return std::numeric_limits<T>::digits; 160*523fa7a6SAndroid Build Coastguard Worker 161*523fa7a6SAndroid Build Coastguard Worker // Bisection method. 162*523fa7a6SAndroid Build Coastguard Worker std::size_t ZeroBits = 0; 163*523fa7a6SAndroid Build Coastguard Worker for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) { 164*523fa7a6SAndroid Build Coastguard Worker T Tmp = Val >> Shift; 165*523fa7a6SAndroid Build Coastguard Worker if (Tmp) 166*523fa7a6SAndroid Build Coastguard Worker Val = Tmp; 167*523fa7a6SAndroid Build Coastguard Worker else 168*523fa7a6SAndroid Build Coastguard Worker ZeroBits |= Shift; 169*523fa7a6SAndroid Build Coastguard Worker } 170*523fa7a6SAndroid Build Coastguard Worker return ZeroBits; 171*523fa7a6SAndroid Build Coastguard Worker } 172*523fa7a6SAndroid Build Coastguard Worker }; 173*523fa7a6SAndroid Build Coastguard Worker 174*523fa7a6SAndroid Build Coastguard Worker #if (defined(__GNUC__) && __GNUC__ >= 4) || defined(_MSC_VER) 175*523fa7a6SAndroid Build Coastguard Worker template <typename T> 176*523fa7a6SAndroid Build Coastguard Worker struct LeadingZerosCounter<T, 4> { 177*523fa7a6SAndroid Build Coastguard Worker static std::size_t count(T Val, ZeroBehavior ZB) { 178*523fa7a6SAndroid Build Coastguard Worker if (ZB != ZB_Undefined && Val == 0) 179*523fa7a6SAndroid Build Coastguard Worker return 32; 180*523fa7a6SAndroid Build Coastguard Worker 181*523fa7a6SAndroid Build Coastguard Worker #if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0) 182*523fa7a6SAndroid Build Coastguard Worker return __builtin_clz(Val); 183*523fa7a6SAndroid Build Coastguard Worker #elif defined(_MSC_VER) 184*523fa7a6SAndroid Build Coastguard Worker unsigned long Index; 185*523fa7a6SAndroid Build Coastguard Worker _BitScanReverse(&Index, Val); 186*523fa7a6SAndroid Build Coastguard Worker return Index ^ 31; 187*523fa7a6SAndroid Build Coastguard Worker #endif 188*523fa7a6SAndroid Build Coastguard Worker } 189*523fa7a6SAndroid Build Coastguard Worker }; 190*523fa7a6SAndroid Build Coastguard Worker 191*523fa7a6SAndroid Build Coastguard Worker #if !defined(_MSC_VER) || defined(_M_X64) 192*523fa7a6SAndroid Build Coastguard Worker template <typename T> 193*523fa7a6SAndroid Build Coastguard Worker struct LeadingZerosCounter<T, 8> { 194*523fa7a6SAndroid Build Coastguard Worker static std::size_t count(T Val, ZeroBehavior ZB) { 195*523fa7a6SAndroid Build Coastguard Worker if (ZB != ZB_Undefined && Val == 0) 196*523fa7a6SAndroid Build Coastguard Worker return 64; 197*523fa7a6SAndroid Build Coastguard Worker 198*523fa7a6SAndroid Build Coastguard Worker #if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0) 199*523fa7a6SAndroid Build Coastguard Worker return __builtin_clzll(Val); 200*523fa7a6SAndroid Build Coastguard Worker #elif defined(_MSC_VER) 201*523fa7a6SAndroid Build Coastguard Worker unsigned long Index; 202*523fa7a6SAndroid Build Coastguard Worker _BitScanReverse64(&Index, Val); 203*523fa7a6SAndroid Build Coastguard Worker return Index ^ 63; 204*523fa7a6SAndroid Build Coastguard Worker #endif 205*523fa7a6SAndroid Build Coastguard Worker } 206*523fa7a6SAndroid Build Coastguard Worker }; 207*523fa7a6SAndroid Build Coastguard Worker #endif 208*523fa7a6SAndroid Build Coastguard Worker #endif 209*523fa7a6SAndroid Build Coastguard Worker } // namespace detail 210*523fa7a6SAndroid Build Coastguard Worker 211*523fa7a6SAndroid Build Coastguard Worker /// Count number of 0's from the most significant bit to the least 212*523fa7a6SAndroid Build Coastguard Worker /// stopping at the first 1. 213*523fa7a6SAndroid Build Coastguard Worker /// 214*523fa7a6SAndroid Build Coastguard Worker /// Only unsigned integral types are allowed. 215*523fa7a6SAndroid Build Coastguard Worker /// 216*523fa7a6SAndroid Build Coastguard Worker /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are 217*523fa7a6SAndroid Build Coastguard Worker /// valid arguments. 218*523fa7a6SAndroid Build Coastguard Worker template <typename T> 219*523fa7a6SAndroid Build Coastguard Worker std::size_t countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { 220*523fa7a6SAndroid Build Coastguard Worker static_assert( 221*523fa7a6SAndroid Build Coastguard Worker std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, 222*523fa7a6SAndroid Build Coastguard Worker "Only unsigned integral types are allowed."); 223*523fa7a6SAndroid Build Coastguard Worker return llvm::detail::LeadingZerosCounter<T, sizeof(T)>::count(Val, ZB); 224*523fa7a6SAndroid Build Coastguard Worker } 225*523fa7a6SAndroid Build Coastguard Worker 226*523fa7a6SAndroid Build Coastguard Worker /// Get the index of the first set bit starting from the least 227*523fa7a6SAndroid Build Coastguard Worker /// significant bit. 228*523fa7a6SAndroid Build Coastguard Worker /// 229*523fa7a6SAndroid Build Coastguard Worker /// Only unsigned integral types are allowed. 230*523fa7a6SAndroid Build Coastguard Worker /// 231*523fa7a6SAndroid Build Coastguard Worker /// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are 232*523fa7a6SAndroid Build Coastguard Worker /// valid arguments. 233*523fa7a6SAndroid Build Coastguard Worker template <typename T> 234*523fa7a6SAndroid Build Coastguard Worker T findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { 235*523fa7a6SAndroid Build Coastguard Worker if (ZB == ZB_Max && Val == 0) 236*523fa7a6SAndroid Build Coastguard Worker return std::numeric_limits<T>::max(); 237*523fa7a6SAndroid Build Coastguard Worker 238*523fa7a6SAndroid Build Coastguard Worker return countTrailingZeros(Val, ZB_Undefined); 239*523fa7a6SAndroid Build Coastguard Worker } 240*523fa7a6SAndroid Build Coastguard Worker 241*523fa7a6SAndroid Build Coastguard Worker /// Create a bitmask with the N right-most bits set to 1, and all other 242*523fa7a6SAndroid Build Coastguard Worker /// bits set to 0. Only unsigned types are allowed. 243*523fa7a6SAndroid Build Coastguard Worker template <typename T> 244*523fa7a6SAndroid Build Coastguard Worker T maskTrailingOnes(unsigned N) { 245*523fa7a6SAndroid Build Coastguard Worker static_assert(std::is_unsigned<T>::value, "Invalid type!"); 246*523fa7a6SAndroid Build Coastguard Worker const unsigned Bits = CHAR_BIT * sizeof(T); 247*523fa7a6SAndroid Build Coastguard Worker assert(N <= Bits && "Invalid bit index"); 248*523fa7a6SAndroid Build Coastguard Worker return N == 0 ? 0 : (T(-1) >> (Bits - N)); 249*523fa7a6SAndroid Build Coastguard Worker } 250*523fa7a6SAndroid Build Coastguard Worker 251*523fa7a6SAndroid Build Coastguard Worker /// Create a bitmask with the N left-most bits set to 1, and all other 252*523fa7a6SAndroid Build Coastguard Worker /// bits set to 0. Only unsigned types are allowed. 253*523fa7a6SAndroid Build Coastguard Worker template <typename T> 254*523fa7a6SAndroid Build Coastguard Worker T maskLeadingOnes(unsigned N) { 255*523fa7a6SAndroid Build Coastguard Worker return ~maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N); 256*523fa7a6SAndroid Build Coastguard Worker } 257*523fa7a6SAndroid Build Coastguard Worker 258*523fa7a6SAndroid Build Coastguard Worker /// Create a bitmask with the N right-most bits set to 0, and all other 259*523fa7a6SAndroid Build Coastguard Worker /// bits set to 1. Only unsigned types are allowed. 260*523fa7a6SAndroid Build Coastguard Worker template <typename T> 261*523fa7a6SAndroid Build Coastguard Worker T maskTrailingZeros(unsigned N) { 262*523fa7a6SAndroid Build Coastguard Worker return maskLeadingOnes<T>(CHAR_BIT * sizeof(T) - N); 263*523fa7a6SAndroid Build Coastguard Worker } 264*523fa7a6SAndroid Build Coastguard Worker 265*523fa7a6SAndroid Build Coastguard Worker /// Create a bitmask with the N left-most bits set to 0, and all other 266*523fa7a6SAndroid Build Coastguard Worker /// bits set to 1. Only unsigned types are allowed. 267*523fa7a6SAndroid Build Coastguard Worker template <typename T> 268*523fa7a6SAndroid Build Coastguard Worker T maskLeadingZeros(unsigned N) { 269*523fa7a6SAndroid Build Coastguard Worker return maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N); 270*523fa7a6SAndroid Build Coastguard Worker } 271*523fa7a6SAndroid Build Coastguard Worker 272*523fa7a6SAndroid Build Coastguard Worker /// Get the index of the last set bit starting from the least 273*523fa7a6SAndroid Build Coastguard Worker /// significant bit. 274*523fa7a6SAndroid Build Coastguard Worker /// 275*523fa7a6SAndroid Build Coastguard Worker /// Only unsigned integral types are allowed. 276*523fa7a6SAndroid Build Coastguard Worker /// 277*523fa7a6SAndroid Build Coastguard Worker /// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are 278*523fa7a6SAndroid Build Coastguard Worker /// valid arguments. 279*523fa7a6SAndroid Build Coastguard Worker template <typename T> 280*523fa7a6SAndroid Build Coastguard Worker T findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { 281*523fa7a6SAndroid Build Coastguard Worker if (ZB == ZB_Max && Val == 0) 282*523fa7a6SAndroid Build Coastguard Worker return std::numeric_limits<T>::max(); 283*523fa7a6SAndroid Build Coastguard Worker 284*523fa7a6SAndroid Build Coastguard Worker // Use ^ instead of - because both gcc and llvm can remove the associated ^ 285*523fa7a6SAndroid Build Coastguard Worker // in the __builtin_clz intrinsic on x86. 286*523fa7a6SAndroid Build Coastguard Worker return countLeadingZeros(Val, ZB_Undefined) ^ 287*523fa7a6SAndroid Build Coastguard Worker (std::numeric_limits<T>::digits - 1); 288*523fa7a6SAndroid Build Coastguard Worker } 289*523fa7a6SAndroid Build Coastguard Worker 290*523fa7a6SAndroid Build Coastguard Worker /// Macro compressed bit reversal table for 256 bits. 291*523fa7a6SAndroid Build Coastguard Worker /// 292*523fa7a6SAndroid Build Coastguard Worker /// http://graphics.stanford.edu/~seander/bithacks.html#BitReverseTable 293*523fa7a6SAndroid Build Coastguard Worker static const unsigned char BitReverseTable256[256] = { 294*523fa7a6SAndroid Build Coastguard Worker #define R2(n) n, n + 2 * 64, n + 1 * 64, n + 3 * 64 295*523fa7a6SAndroid Build Coastguard Worker #define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16) 296*523fa7a6SAndroid Build Coastguard Worker #define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4) 297*523fa7a6SAndroid Build Coastguard Worker R6(0), 298*523fa7a6SAndroid Build Coastguard Worker R6(2), 299*523fa7a6SAndroid Build Coastguard Worker R6(1), 300*523fa7a6SAndroid Build Coastguard Worker R6(3) 301*523fa7a6SAndroid Build Coastguard Worker #undef R2 302*523fa7a6SAndroid Build Coastguard Worker #undef R4 303*523fa7a6SAndroid Build Coastguard Worker #undef R6 304*523fa7a6SAndroid Build Coastguard Worker }; 305*523fa7a6SAndroid Build Coastguard Worker 306*523fa7a6SAndroid Build Coastguard Worker /// Reverse the bits in \p Val. 307*523fa7a6SAndroid Build Coastguard Worker template <typename T> 308*523fa7a6SAndroid Build Coastguard Worker T reverseBits(T Val) { 309*523fa7a6SAndroid Build Coastguard Worker unsigned char in[sizeof(Val)]; 310*523fa7a6SAndroid Build Coastguard Worker unsigned char out[sizeof(Val)]; 311*523fa7a6SAndroid Build Coastguard Worker std::memcpy(in, &Val, sizeof(Val)); 312*523fa7a6SAndroid Build Coastguard Worker for (unsigned i = 0; i < sizeof(Val); ++i) 313*523fa7a6SAndroid Build Coastguard Worker out[(sizeof(Val) - i) - 1] = BitReverseTable256[in[i]]; 314*523fa7a6SAndroid Build Coastguard Worker std::memcpy(&Val, out, sizeof(Val)); 315*523fa7a6SAndroid Build Coastguard Worker return Val; 316*523fa7a6SAndroid Build Coastguard Worker } 317*523fa7a6SAndroid Build Coastguard Worker 318*523fa7a6SAndroid Build Coastguard Worker // NOTE: The following support functions use the _32/_64 extensions instead of 319*523fa7a6SAndroid Build Coastguard Worker // type overloading so that signed and unsigned integers can be used without 320*523fa7a6SAndroid Build Coastguard Worker // ambiguity. 321*523fa7a6SAndroid Build Coastguard Worker 322*523fa7a6SAndroid Build Coastguard Worker /// Return the high 32 bits of a 64 bit value. 323*523fa7a6SAndroid Build Coastguard Worker constexpr inline uint32_t Hi_32(uint64_t Value) { 324*523fa7a6SAndroid Build Coastguard Worker return static_cast<uint32_t>(Value >> 32); 325*523fa7a6SAndroid Build Coastguard Worker } 326*523fa7a6SAndroid Build Coastguard Worker 327*523fa7a6SAndroid Build Coastguard Worker /// Return the low 32 bits of a 64 bit value. 328*523fa7a6SAndroid Build Coastguard Worker constexpr inline uint32_t Lo_32(uint64_t Value) { 329*523fa7a6SAndroid Build Coastguard Worker return static_cast<uint32_t>(Value); 330*523fa7a6SAndroid Build Coastguard Worker } 331*523fa7a6SAndroid Build Coastguard Worker 332*523fa7a6SAndroid Build Coastguard Worker /// Make a 64-bit integer from a high / low pair of 32-bit integers. 333*523fa7a6SAndroid Build Coastguard Worker constexpr inline uint64_t Make_64(uint32_t High, uint32_t Low) { 334*523fa7a6SAndroid Build Coastguard Worker return ((uint64_t)High << 32) | (uint64_t)Low; 335*523fa7a6SAndroid Build Coastguard Worker } 336*523fa7a6SAndroid Build Coastguard Worker 337*523fa7a6SAndroid Build Coastguard Worker /// Checks if an integer fits into the given bit width. 338*523fa7a6SAndroid Build Coastguard Worker template <unsigned N> 339*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isInt(int64_t x) { 340*523fa7a6SAndroid Build Coastguard Worker return N >= 64 || 341*523fa7a6SAndroid Build Coastguard Worker (-(INT64_C(1) << (N - 1)) <= x && x < (INT64_C(1) << (N - 1))); 342*523fa7a6SAndroid Build Coastguard Worker } 343*523fa7a6SAndroid Build Coastguard Worker // Template specializations to get better code for common cases. 344*523fa7a6SAndroid Build Coastguard Worker template <> 345*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isInt<8>(int64_t x) { 346*523fa7a6SAndroid Build Coastguard Worker return static_cast<int8_t>(x) == x; 347*523fa7a6SAndroid Build Coastguard Worker } 348*523fa7a6SAndroid Build Coastguard Worker template <> 349*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isInt<16>(int64_t x) { 350*523fa7a6SAndroid Build Coastguard Worker return static_cast<int16_t>(x) == x; 351*523fa7a6SAndroid Build Coastguard Worker } 352*523fa7a6SAndroid Build Coastguard Worker template <> 353*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isInt<32>(int64_t x) { 354*523fa7a6SAndroid Build Coastguard Worker return static_cast<int32_t>(x) == x; 355*523fa7a6SAndroid Build Coastguard Worker } 356*523fa7a6SAndroid Build Coastguard Worker 357*523fa7a6SAndroid Build Coastguard Worker /// Checks if a signed integer is an N bit number shifted left by S. 358*523fa7a6SAndroid Build Coastguard Worker template <unsigned N, unsigned S> 359*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isShiftedInt(int64_t x) { 360*523fa7a6SAndroid Build Coastguard Worker static_assert( 361*523fa7a6SAndroid Build Coastguard Worker N > 0, "isShiftedInt<0> doesn't make sense (refers to a 0-bit number."); 362*523fa7a6SAndroid Build Coastguard Worker static_assert(N + S <= 64, "isShiftedInt<N, S> with N + S > 64 is too wide."); 363*523fa7a6SAndroid Build Coastguard Worker return isInt<N + S>(x) && (x % (UINT64_C(1) << S) == 0); 364*523fa7a6SAndroid Build Coastguard Worker } 365*523fa7a6SAndroid Build Coastguard Worker 366*523fa7a6SAndroid Build Coastguard Worker /// Checks if an unsigned integer fits into the given bit width. 367*523fa7a6SAndroid Build Coastguard Worker /// 368*523fa7a6SAndroid Build Coastguard Worker /// This is written as two functions rather than as simply 369*523fa7a6SAndroid Build Coastguard Worker /// 370*523fa7a6SAndroid Build Coastguard Worker /// return N >= 64 || X < (UINT64_C(1) << N); 371*523fa7a6SAndroid Build Coastguard Worker /// 372*523fa7a6SAndroid Build Coastguard Worker /// to keep MSVC from (incorrectly) warning on isUInt<64> that we're shifting 373*523fa7a6SAndroid Build Coastguard Worker /// left too many places. 374*523fa7a6SAndroid Build Coastguard Worker template <unsigned N> 375*523fa7a6SAndroid Build Coastguard Worker constexpr inline typename std::enable_if<(N < 64), bool>::type isUInt( 376*523fa7a6SAndroid Build Coastguard Worker uint64_t X) { 377*523fa7a6SAndroid Build Coastguard Worker static_assert(N > 0, "isUInt<0> doesn't make sense"); 378*523fa7a6SAndroid Build Coastguard Worker return X < (UINT64_C(1) << (N)); 379*523fa7a6SAndroid Build Coastguard Worker } 380*523fa7a6SAndroid Build Coastguard Worker template <unsigned N> 381*523fa7a6SAndroid Build Coastguard Worker constexpr inline typename std::enable_if<N >= 64, bool>::type isUInt( 382*523fa7a6SAndroid Build Coastguard Worker uint64_t /*X*/) { 383*523fa7a6SAndroid Build Coastguard Worker return true; 384*523fa7a6SAndroid Build Coastguard Worker } 385*523fa7a6SAndroid Build Coastguard Worker 386*523fa7a6SAndroid Build Coastguard Worker // Template specializations to get better code for common cases. 387*523fa7a6SAndroid Build Coastguard Worker template <> 388*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isUInt<8>(uint64_t x) { 389*523fa7a6SAndroid Build Coastguard Worker return static_cast<uint8_t>(x) == x; 390*523fa7a6SAndroid Build Coastguard Worker } 391*523fa7a6SAndroid Build Coastguard Worker template <> 392*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isUInt<16>(uint64_t x) { 393*523fa7a6SAndroid Build Coastguard Worker return static_cast<uint16_t>(x) == x; 394*523fa7a6SAndroid Build Coastguard Worker } 395*523fa7a6SAndroid Build Coastguard Worker template <> 396*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isUInt<32>(uint64_t x) { 397*523fa7a6SAndroid Build Coastguard Worker return static_cast<uint32_t>(x) == x; 398*523fa7a6SAndroid Build Coastguard Worker } 399*523fa7a6SAndroid Build Coastguard Worker 400*523fa7a6SAndroid Build Coastguard Worker /// Checks if a unsigned integer is an N bit number shifted left by S. 401*523fa7a6SAndroid Build Coastguard Worker template <unsigned N, unsigned S> 402*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isShiftedUInt(uint64_t x) { 403*523fa7a6SAndroid Build Coastguard Worker static_assert( 404*523fa7a6SAndroid Build Coastguard Worker N > 0, "isShiftedUInt<0> doesn't make sense (refers to a 0-bit number)"); 405*523fa7a6SAndroid Build Coastguard Worker static_assert( 406*523fa7a6SAndroid Build Coastguard Worker N + S <= 64, "isShiftedUInt<N, S> with N + S > 64 is too wide."); 407*523fa7a6SAndroid Build Coastguard Worker // Per the two static_asserts above, S must be strictly less than 64. So 408*523fa7a6SAndroid Build Coastguard Worker // 1 << S is not undefined behavior. 409*523fa7a6SAndroid Build Coastguard Worker return isUInt<N + S>(x) && (x % (UINT64_C(1) << S) == 0); 410*523fa7a6SAndroid Build Coastguard Worker } 411*523fa7a6SAndroid Build Coastguard Worker 412*523fa7a6SAndroid Build Coastguard Worker /// Gets the maximum value for a N-bit unsigned integer. 413*523fa7a6SAndroid Build Coastguard Worker inline uint64_t maxUIntN(uint64_t N) { 414*523fa7a6SAndroid Build Coastguard Worker assert(N > 0 && N <= 64 && "integer width out of range"); 415*523fa7a6SAndroid Build Coastguard Worker 416*523fa7a6SAndroid Build Coastguard Worker // uint64_t(1) << 64 is undefined behavior, so we can't do 417*523fa7a6SAndroid Build Coastguard Worker // (uint64_t(1) << N) - 1 418*523fa7a6SAndroid Build Coastguard Worker // without checking first that N != 64. But this works and doesn't have a 419*523fa7a6SAndroid Build Coastguard Worker // branch. 420*523fa7a6SAndroid Build Coastguard Worker return UINT64_MAX >> (64 - N); 421*523fa7a6SAndroid Build Coastguard Worker } 422*523fa7a6SAndroid Build Coastguard Worker 423*523fa7a6SAndroid Build Coastguard Worker // Ignore the false warning "Arithmetic overflow" for MSVC 424*523fa7a6SAndroid Build Coastguard Worker #ifdef _MSC_VER 425*523fa7a6SAndroid Build Coastguard Worker #pragma warning(push) 426*523fa7a6SAndroid Build Coastguard Worker #pragma warning(disable : 4146) 427*523fa7a6SAndroid Build Coastguard Worker #endif 428*523fa7a6SAndroid Build Coastguard Worker 429*523fa7a6SAndroid Build Coastguard Worker /// Gets the minimum value for a N-bit signed integer. 430*523fa7a6SAndroid Build Coastguard Worker inline int64_t minIntN(int64_t N) { 431*523fa7a6SAndroid Build Coastguard Worker assert(N > 0 && N <= 64 && "integer width out of range"); 432*523fa7a6SAndroid Build Coastguard Worker 433*523fa7a6SAndroid Build Coastguard Worker return -(UINT64_C(1) << (N - 1)); 434*523fa7a6SAndroid Build Coastguard Worker } 435*523fa7a6SAndroid Build Coastguard Worker 436*523fa7a6SAndroid Build Coastguard Worker #ifdef _MSC_VER 437*523fa7a6SAndroid Build Coastguard Worker #pragma warning(pop) 438*523fa7a6SAndroid Build Coastguard Worker #endif 439*523fa7a6SAndroid Build Coastguard Worker 440*523fa7a6SAndroid Build Coastguard Worker /// Gets the maximum value for a N-bit signed integer. 441*523fa7a6SAndroid Build Coastguard Worker inline int64_t maxIntN(int64_t N) { 442*523fa7a6SAndroid Build Coastguard Worker assert(N > 0 && N <= 64 && "integer width out of range"); 443*523fa7a6SAndroid Build Coastguard Worker 444*523fa7a6SAndroid Build Coastguard Worker // This relies on two's complement wraparound when N == 64, so we convert to 445*523fa7a6SAndroid Build Coastguard Worker // int64_t only at the very end to avoid UB. 446*523fa7a6SAndroid Build Coastguard Worker return (UINT64_C(1) << (N - 1)) - 1; 447*523fa7a6SAndroid Build Coastguard Worker } 448*523fa7a6SAndroid Build Coastguard Worker 449*523fa7a6SAndroid Build Coastguard Worker /// Checks if an unsigned integer fits into the given (dynamic) bit width. 450*523fa7a6SAndroid Build Coastguard Worker inline bool isUIntN(unsigned N, uint64_t x) { 451*523fa7a6SAndroid Build Coastguard Worker return N >= 64 || x <= maxUIntN(N); 452*523fa7a6SAndroid Build Coastguard Worker } 453*523fa7a6SAndroid Build Coastguard Worker 454*523fa7a6SAndroid Build Coastguard Worker /// Checks if an signed integer fits into the given (dynamic) bit width. 455*523fa7a6SAndroid Build Coastguard Worker inline bool isIntN(unsigned N, int64_t x) { 456*523fa7a6SAndroid Build Coastguard Worker return N >= 64 || (minIntN(N) <= x && x <= maxIntN(N)); 457*523fa7a6SAndroid Build Coastguard Worker } 458*523fa7a6SAndroid Build Coastguard Worker 459*523fa7a6SAndroid Build Coastguard Worker /// Return true if the argument is a non-empty sequence of ones starting at the 460*523fa7a6SAndroid Build Coastguard Worker /// least significant bit with the remainder zero (32 bit version). 461*523fa7a6SAndroid Build Coastguard Worker /// Ex. isMask_32(0x0000FFFFU) == true. 462*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isMask_32(uint32_t Value) { 463*523fa7a6SAndroid Build Coastguard Worker return Value && ((Value + 1) & Value) == 0; 464*523fa7a6SAndroid Build Coastguard Worker } 465*523fa7a6SAndroid Build Coastguard Worker 466*523fa7a6SAndroid Build Coastguard Worker /// Return true if the argument is a non-empty sequence of ones starting at the 467*523fa7a6SAndroid Build Coastguard Worker /// least significant bit with the remainder zero (64 bit version). 468*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isMask_64(uint64_t Value) { 469*523fa7a6SAndroid Build Coastguard Worker return Value && ((Value + 1) & Value) == 0; 470*523fa7a6SAndroid Build Coastguard Worker } 471*523fa7a6SAndroid Build Coastguard Worker 472*523fa7a6SAndroid Build Coastguard Worker /// Return true if the argument contains a non-empty sequence of ones with the 473*523fa7a6SAndroid Build Coastguard Worker /// remainder zero (32 bit version.) Ex. isShiftedMask_32(0x0000FF00U) == true. 474*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isShiftedMask_32(uint32_t Value) { 475*523fa7a6SAndroid Build Coastguard Worker return Value && isMask_32((Value - 1) | Value); 476*523fa7a6SAndroid Build Coastguard Worker } 477*523fa7a6SAndroid Build Coastguard Worker 478*523fa7a6SAndroid Build Coastguard Worker /// Return true if the argument contains a non-empty sequence of ones with the 479*523fa7a6SAndroid Build Coastguard Worker /// remainder zero (64 bit version.) 480*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isShiftedMask_64(uint64_t Value) { 481*523fa7a6SAndroid Build Coastguard Worker return Value && isMask_64((Value - 1) | Value); 482*523fa7a6SAndroid Build Coastguard Worker } 483*523fa7a6SAndroid Build Coastguard Worker 484*523fa7a6SAndroid Build Coastguard Worker /// Return true if the argument is a power of two > 0. 485*523fa7a6SAndroid Build Coastguard Worker /// Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.) 486*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isPowerOf2_32(uint32_t Value) { 487*523fa7a6SAndroid Build Coastguard Worker return Value && !(Value & (Value - 1)); 488*523fa7a6SAndroid Build Coastguard Worker } 489*523fa7a6SAndroid Build Coastguard Worker 490*523fa7a6SAndroid Build Coastguard Worker /// Return true if the argument is a power of two > 0 (64 bit edition.) 491*523fa7a6SAndroid Build Coastguard Worker constexpr inline bool isPowerOf2_64(uint64_t Value) { 492*523fa7a6SAndroid Build Coastguard Worker return Value && !(Value & (Value - 1)); 493*523fa7a6SAndroid Build Coastguard Worker } 494*523fa7a6SAndroid Build Coastguard Worker 495*523fa7a6SAndroid Build Coastguard Worker /// Count the number of ones from the most significant bit to the first 496*523fa7a6SAndroid Build Coastguard Worker /// zero bit. 497*523fa7a6SAndroid Build Coastguard Worker /// 498*523fa7a6SAndroid Build Coastguard Worker /// Ex. countLeadingOnes(0xFF0FFF00) == 8. 499*523fa7a6SAndroid Build Coastguard Worker /// Only unsigned integral types are allowed. 500*523fa7a6SAndroid Build Coastguard Worker /// 501*523fa7a6SAndroid Build Coastguard Worker /// \param ZB the behavior on an input of all ones. Only ZB_Width and 502*523fa7a6SAndroid Build Coastguard Worker /// ZB_Undefined are valid arguments. 503*523fa7a6SAndroid Build Coastguard Worker template <typename T> 504*523fa7a6SAndroid Build Coastguard Worker std::size_t countLeadingOnes(T Value, ZeroBehavior ZB = ZB_Width) { 505*523fa7a6SAndroid Build Coastguard Worker static_assert( 506*523fa7a6SAndroid Build Coastguard Worker std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, 507*523fa7a6SAndroid Build Coastguard Worker "Only unsigned integral types are allowed."); 508*523fa7a6SAndroid Build Coastguard Worker return countLeadingZeros<T>(~Value, ZB); 509*523fa7a6SAndroid Build Coastguard Worker } 510*523fa7a6SAndroid Build Coastguard Worker 511*523fa7a6SAndroid Build Coastguard Worker /// Count the number of ones from the least significant bit to the first 512*523fa7a6SAndroid Build Coastguard Worker /// zero bit. 513*523fa7a6SAndroid Build Coastguard Worker /// 514*523fa7a6SAndroid Build Coastguard Worker /// Ex. countTrailingOnes(0x00FF00FF) == 8. 515*523fa7a6SAndroid Build Coastguard Worker /// Only unsigned integral types are allowed. 516*523fa7a6SAndroid Build Coastguard Worker /// 517*523fa7a6SAndroid Build Coastguard Worker /// \param ZB the behavior on an input of all ones. Only ZB_Width and 518*523fa7a6SAndroid Build Coastguard Worker /// ZB_Undefined are valid arguments. 519*523fa7a6SAndroid Build Coastguard Worker template <typename T> 520*523fa7a6SAndroid Build Coastguard Worker std::size_t countTrailingOnes(T Value, ZeroBehavior ZB = ZB_Width) { 521*523fa7a6SAndroid Build Coastguard Worker static_assert( 522*523fa7a6SAndroid Build Coastguard Worker std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, 523*523fa7a6SAndroid Build Coastguard Worker "Only unsigned integral types are allowed."); 524*523fa7a6SAndroid Build Coastguard Worker return countTrailingZeros<T>(~Value, ZB); 525*523fa7a6SAndroid Build Coastguard Worker } 526*523fa7a6SAndroid Build Coastguard Worker 527*523fa7a6SAndroid Build Coastguard Worker namespace detail { 528*523fa7a6SAndroid Build Coastguard Worker template <typename T, std::size_t SizeOfT> 529*523fa7a6SAndroid Build Coastguard Worker struct PopulationCounter { 530*523fa7a6SAndroid Build Coastguard Worker static unsigned count(T Value) { 531*523fa7a6SAndroid Build Coastguard Worker // Generic version, forward to 32 bits. 532*523fa7a6SAndroid Build Coastguard Worker static_assert(SizeOfT <= 4, "Not implemented!"); 533*523fa7a6SAndroid Build Coastguard Worker #if defined(__GNUC__) && __GNUC__ >= 4 534*523fa7a6SAndroid Build Coastguard Worker return __builtin_popcount(Value); 535*523fa7a6SAndroid Build Coastguard Worker #else 536*523fa7a6SAndroid Build Coastguard Worker uint32_t v = Value; 537*523fa7a6SAndroid Build Coastguard Worker v = v - ((v >> 1) & 0x55555555); 538*523fa7a6SAndroid Build Coastguard Worker v = (v & 0x33333333) + ((v >> 2) & 0x33333333); 539*523fa7a6SAndroid Build Coastguard Worker return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; 540*523fa7a6SAndroid Build Coastguard Worker #endif 541*523fa7a6SAndroid Build Coastguard Worker } 542*523fa7a6SAndroid Build Coastguard Worker }; 543*523fa7a6SAndroid Build Coastguard Worker 544*523fa7a6SAndroid Build Coastguard Worker template <typename T> 545*523fa7a6SAndroid Build Coastguard Worker struct PopulationCounter<T, 8> { 546*523fa7a6SAndroid Build Coastguard Worker static unsigned count(T Value) { 547*523fa7a6SAndroid Build Coastguard Worker #if defined(__GNUC__) && __GNUC__ >= 4 548*523fa7a6SAndroid Build Coastguard Worker return __builtin_popcountll(Value); 549*523fa7a6SAndroid Build Coastguard Worker #else 550*523fa7a6SAndroid Build Coastguard Worker uint64_t v = Value; 551*523fa7a6SAndroid Build Coastguard Worker v = v - ((v >> 1) & 0x5555555555555555ULL); 552*523fa7a6SAndroid Build Coastguard Worker v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL); 553*523fa7a6SAndroid Build Coastguard Worker v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL; 554*523fa7a6SAndroid Build Coastguard Worker return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56); 555*523fa7a6SAndroid Build Coastguard Worker #endif 556*523fa7a6SAndroid Build Coastguard Worker } 557*523fa7a6SAndroid Build Coastguard Worker }; 558*523fa7a6SAndroid Build Coastguard Worker } // namespace detail 559*523fa7a6SAndroid Build Coastguard Worker 560*523fa7a6SAndroid Build Coastguard Worker /// Count the number of set bits in a value. 561*523fa7a6SAndroid Build Coastguard Worker /// Ex. countPopulation(0xF000F000) = 8 562*523fa7a6SAndroid Build Coastguard Worker /// Returns 0 if the word is zero. 563*523fa7a6SAndroid Build Coastguard Worker template <typename T> 564*523fa7a6SAndroid Build Coastguard Worker inline unsigned countPopulation(T Value) { 565*523fa7a6SAndroid Build Coastguard Worker static_assert( 566*523fa7a6SAndroid Build Coastguard Worker std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed, 567*523fa7a6SAndroid Build Coastguard Worker "Only unsigned integral types are allowed."); 568*523fa7a6SAndroid Build Coastguard Worker return detail::PopulationCounter<T, sizeof(T)>::count(Value); 569*523fa7a6SAndroid Build Coastguard Worker } 570*523fa7a6SAndroid Build Coastguard Worker 571*523fa7a6SAndroid Build Coastguard Worker /// Return the log base 2 of the specified value. 572*523fa7a6SAndroid Build Coastguard Worker inline double Log2(double Value) { 573*523fa7a6SAndroid Build Coastguard Worker #if defined(__ANDROID_API__) && __ANDROID_API__ < 18 574*523fa7a6SAndroid Build Coastguard Worker return __builtin_log(Value) / __builtin_log(2.0); 575*523fa7a6SAndroid Build Coastguard Worker #else 576*523fa7a6SAndroid Build Coastguard Worker return log2(Value); 577*523fa7a6SAndroid Build Coastguard Worker #endif 578*523fa7a6SAndroid Build Coastguard Worker } 579*523fa7a6SAndroid Build Coastguard Worker 580*523fa7a6SAndroid Build Coastguard Worker /// Return the floor log base 2 of the specified value, -1 if the value is zero. 581*523fa7a6SAndroid Build Coastguard Worker /// (32 bit edition.) 582*523fa7a6SAndroid Build Coastguard Worker /// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2 583*523fa7a6SAndroid Build Coastguard Worker inline unsigned Log2_32(uint32_t Value) { 584*523fa7a6SAndroid Build Coastguard Worker return static_cast<unsigned>(31 - countLeadingZeros(Value)); 585*523fa7a6SAndroid Build Coastguard Worker } 586*523fa7a6SAndroid Build Coastguard Worker 587*523fa7a6SAndroid Build Coastguard Worker /// Return the floor log base 2 of the specified value, -1 if the value is zero. 588*523fa7a6SAndroid Build Coastguard Worker /// (64 bit edition.) 589*523fa7a6SAndroid Build Coastguard Worker inline unsigned Log2_64(uint64_t Value) { 590*523fa7a6SAndroid Build Coastguard Worker return static_cast<unsigned>(63 - countLeadingZeros(Value)); 591*523fa7a6SAndroid Build Coastguard Worker } 592*523fa7a6SAndroid Build Coastguard Worker 593*523fa7a6SAndroid Build Coastguard Worker /// Return the ceil log base 2 of the specified value, 32 if the value is zero. 594*523fa7a6SAndroid Build Coastguard Worker /// (32 bit edition). 595*523fa7a6SAndroid Build Coastguard Worker /// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3 596*523fa7a6SAndroid Build Coastguard Worker inline unsigned Log2_32_Ceil(uint32_t Value) { 597*523fa7a6SAndroid Build Coastguard Worker return static_cast<unsigned>(32 - countLeadingZeros(Value - 1)); 598*523fa7a6SAndroid Build Coastguard Worker } 599*523fa7a6SAndroid Build Coastguard Worker 600*523fa7a6SAndroid Build Coastguard Worker /// Return the ceil log base 2 of the specified value, 64 if the value is zero. 601*523fa7a6SAndroid Build Coastguard Worker /// (64 bit edition.) 602*523fa7a6SAndroid Build Coastguard Worker inline unsigned Log2_64_Ceil(uint64_t Value) { 603*523fa7a6SAndroid Build Coastguard Worker return static_cast<unsigned>(64 - countLeadingZeros(Value - 1)); 604*523fa7a6SAndroid Build Coastguard Worker } 605*523fa7a6SAndroid Build Coastguard Worker 606*523fa7a6SAndroid Build Coastguard Worker /// Return the greatest common divisor of the values using Euclid's algorithm. 607*523fa7a6SAndroid Build Coastguard Worker inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) { 608*523fa7a6SAndroid Build Coastguard Worker while (B) { 609*523fa7a6SAndroid Build Coastguard Worker uint64_t T = B; 610*523fa7a6SAndroid Build Coastguard Worker B = A % B; 611*523fa7a6SAndroid Build Coastguard Worker A = T; 612*523fa7a6SAndroid Build Coastguard Worker } 613*523fa7a6SAndroid Build Coastguard Worker return A; 614*523fa7a6SAndroid Build Coastguard Worker } 615*523fa7a6SAndroid Build Coastguard Worker 616*523fa7a6SAndroid Build Coastguard Worker /// This function takes a 64-bit integer and returns the bit equivalent double. 617*523fa7a6SAndroid Build Coastguard Worker inline double BitsToDouble(uint64_t Bits) { 618*523fa7a6SAndroid Build Coastguard Worker double D; 619*523fa7a6SAndroid Build Coastguard Worker static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes"); 620*523fa7a6SAndroid Build Coastguard Worker memcpy(&D, &Bits, sizeof(Bits)); 621*523fa7a6SAndroid Build Coastguard Worker return D; 622*523fa7a6SAndroid Build Coastguard Worker } 623*523fa7a6SAndroid Build Coastguard Worker 624*523fa7a6SAndroid Build Coastguard Worker /// This function takes a 32-bit integer and returns the bit equivalent float. 625*523fa7a6SAndroid Build Coastguard Worker inline float BitsToFloat(uint32_t Bits) { 626*523fa7a6SAndroid Build Coastguard Worker // TODO: Use bit_cast once C++20 becomes available. 627*523fa7a6SAndroid Build Coastguard Worker float F; 628*523fa7a6SAndroid Build Coastguard Worker static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes"); 629*523fa7a6SAndroid Build Coastguard Worker memcpy(&F, &Bits, sizeof(Bits)); 630*523fa7a6SAndroid Build Coastguard Worker return F; 631*523fa7a6SAndroid Build Coastguard Worker } 632*523fa7a6SAndroid Build Coastguard Worker 633*523fa7a6SAndroid Build Coastguard Worker /// This function takes a double and returns the bit equivalent 64-bit integer. 634*523fa7a6SAndroid Build Coastguard Worker /// Note that copying doubles around changes the bits of NaNs on some hosts, 635*523fa7a6SAndroid Build Coastguard Worker /// notably x86, so this routine cannot be used if these bits are needed. 636*523fa7a6SAndroid Build Coastguard Worker inline uint64_t DoubleToBits(double Double) { 637*523fa7a6SAndroid Build Coastguard Worker uint64_t Bits; 638*523fa7a6SAndroid Build Coastguard Worker static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes"); 639*523fa7a6SAndroid Build Coastguard Worker memcpy(&Bits, &Double, sizeof(Double)); 640*523fa7a6SAndroid Build Coastguard Worker return Bits; 641*523fa7a6SAndroid Build Coastguard Worker } 642*523fa7a6SAndroid Build Coastguard Worker 643*523fa7a6SAndroid Build Coastguard Worker /// This function takes a float and returns the bit equivalent 32-bit integer. 644*523fa7a6SAndroid Build Coastguard Worker /// Note that copying floats around changes the bits of NaNs on some hosts, 645*523fa7a6SAndroid Build Coastguard Worker /// notably x86, so this routine cannot be used if these bits are needed. 646*523fa7a6SAndroid Build Coastguard Worker inline uint32_t FloatToBits(float Float) { 647*523fa7a6SAndroid Build Coastguard Worker uint32_t Bits; 648*523fa7a6SAndroid Build Coastguard Worker static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes"); 649*523fa7a6SAndroid Build Coastguard Worker memcpy(&Bits, &Float, sizeof(Float)); 650*523fa7a6SAndroid Build Coastguard Worker return Bits; 651*523fa7a6SAndroid Build Coastguard Worker } 652*523fa7a6SAndroid Build Coastguard Worker 653*523fa7a6SAndroid Build Coastguard Worker /// A and B are either alignments or offsets. Return the minimum alignment that 654*523fa7a6SAndroid Build Coastguard Worker /// may be assumed after adding the two together. 655*523fa7a6SAndroid Build Coastguard Worker constexpr inline uint64_t MinAlign(uint64_t A, uint64_t B) { 656*523fa7a6SAndroid Build Coastguard Worker // The largest power of 2 that divides both A and B. 657*523fa7a6SAndroid Build Coastguard Worker // 658*523fa7a6SAndroid Build Coastguard Worker // Replace "-Value" by "1+~Value" in the following commented code to avoid 659*523fa7a6SAndroid Build Coastguard Worker // MSVC warning C4146 660*523fa7a6SAndroid Build Coastguard Worker // return (A | B) & -(A | B); 661*523fa7a6SAndroid Build Coastguard Worker return (A | B) & (1 + ~(A | B)); 662*523fa7a6SAndroid Build Coastguard Worker } 663*523fa7a6SAndroid Build Coastguard Worker 664*523fa7a6SAndroid Build Coastguard Worker /// Aligns \c Addr to \c Alignment bytes, rounding up. 665*523fa7a6SAndroid Build Coastguard Worker /// 666*523fa7a6SAndroid Build Coastguard Worker /// Alignment should be a power of two. This method rounds up, so 667*523fa7a6SAndroid Build Coastguard Worker /// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8. 668*523fa7a6SAndroid Build Coastguard Worker inline uintptr_t alignAddr(const void* Addr, size_t Alignment) { 669*523fa7a6SAndroid Build Coastguard Worker assert( 670*523fa7a6SAndroid Build Coastguard Worker Alignment && isPowerOf2_64((uint64_t)Alignment) && 671*523fa7a6SAndroid Build Coastguard Worker "Alignment is not a power of two!"); 672*523fa7a6SAndroid Build Coastguard Worker 673*523fa7a6SAndroid Build Coastguard Worker assert((uintptr_t)Addr + Alignment - 1 >= (uintptr_t)Addr); 674*523fa7a6SAndroid Build Coastguard Worker 675*523fa7a6SAndroid Build Coastguard Worker return (((uintptr_t)Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1)); 676*523fa7a6SAndroid Build Coastguard Worker } 677*523fa7a6SAndroid Build Coastguard Worker 678*523fa7a6SAndroid Build Coastguard Worker /// Returns the necessary adjustment for aligning \c Ptr to \c Alignment 679*523fa7a6SAndroid Build Coastguard Worker /// bytes, rounding up. 680*523fa7a6SAndroid Build Coastguard Worker inline size_t alignmentAdjustment(const void* Ptr, size_t Alignment) { 681*523fa7a6SAndroid Build Coastguard Worker return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr; 682*523fa7a6SAndroid Build Coastguard Worker } 683*523fa7a6SAndroid Build Coastguard Worker 684*523fa7a6SAndroid Build Coastguard Worker /// Returns the next power of two (in 64-bits) that is strictly greater than A. 685*523fa7a6SAndroid Build Coastguard Worker /// Returns zero on overflow. 686*523fa7a6SAndroid Build Coastguard Worker inline uint64_t NextPowerOf2(uint64_t A) { 687*523fa7a6SAndroid Build Coastguard Worker A |= (A >> 1); 688*523fa7a6SAndroid Build Coastguard Worker A |= (A >> 2); 689*523fa7a6SAndroid Build Coastguard Worker A |= (A >> 4); 690*523fa7a6SAndroid Build Coastguard Worker A |= (A >> 8); 691*523fa7a6SAndroid Build Coastguard Worker A |= (A >> 16); 692*523fa7a6SAndroid Build Coastguard Worker A |= (A >> 32); 693*523fa7a6SAndroid Build Coastguard Worker return A + 1; 694*523fa7a6SAndroid Build Coastguard Worker } 695*523fa7a6SAndroid Build Coastguard Worker 696*523fa7a6SAndroid Build Coastguard Worker /// Returns the power of two which is less than or equal to the given value. 697*523fa7a6SAndroid Build Coastguard Worker /// Essentially, it is a floor operation across the domain of powers of two. 698*523fa7a6SAndroid Build Coastguard Worker inline uint64_t PowerOf2Floor(uint64_t A) { 699*523fa7a6SAndroid Build Coastguard Worker if (!A) 700*523fa7a6SAndroid Build Coastguard Worker return 0; 701*523fa7a6SAndroid Build Coastguard Worker return 1ull << (63 - countLeadingZeros(A, ZB_Undefined)); 702*523fa7a6SAndroid Build Coastguard Worker } 703*523fa7a6SAndroid Build Coastguard Worker 704*523fa7a6SAndroid Build Coastguard Worker /// Returns the power of two which is greater than or equal to the given value. 705*523fa7a6SAndroid Build Coastguard Worker /// Essentially, it is a ceil operation across the domain of powers of two. 706*523fa7a6SAndroid Build Coastguard Worker inline uint64_t PowerOf2Ceil(uint64_t A) { 707*523fa7a6SAndroid Build Coastguard Worker if (!A) 708*523fa7a6SAndroid Build Coastguard Worker return 0; 709*523fa7a6SAndroid Build Coastguard Worker return NextPowerOf2(A - 1); 710*523fa7a6SAndroid Build Coastguard Worker } 711*523fa7a6SAndroid Build Coastguard Worker 712*523fa7a6SAndroid Build Coastguard Worker /// Returns the next integer (mod 2**64) that is greater than or equal to 713*523fa7a6SAndroid Build Coastguard Worker /// \p Value and is a multiple of \p Align. \p Align must be non-zero. 714*523fa7a6SAndroid Build Coastguard Worker /// 715*523fa7a6SAndroid Build Coastguard Worker /// If non-zero \p Skew is specified, the return value will be a minimal 716*523fa7a6SAndroid Build Coastguard Worker /// integer that is greater than or equal to \p Value and equal to 717*523fa7a6SAndroid Build Coastguard Worker /// \p Align * N + \p Skew for some integer N. If \p Skew is larger than 718*523fa7a6SAndroid Build Coastguard Worker /// \p Align, its value is adjusted to '\p Skew mod \p Align'. 719*523fa7a6SAndroid Build Coastguard Worker /// 720*523fa7a6SAndroid Build Coastguard Worker /// Examples: 721*523fa7a6SAndroid Build Coastguard Worker /// \code 722*523fa7a6SAndroid Build Coastguard Worker /// alignTo(5, 8) = 8 723*523fa7a6SAndroid Build Coastguard Worker /// alignTo(17, 8) = 24 724*523fa7a6SAndroid Build Coastguard Worker /// alignTo(~0LL, 8) = 0 725*523fa7a6SAndroid Build Coastguard Worker /// alignTo(321, 255) = 510 726*523fa7a6SAndroid Build Coastguard Worker /// 727*523fa7a6SAndroid Build Coastguard Worker /// alignTo(5, 8, 7) = 7 728*523fa7a6SAndroid Build Coastguard Worker /// alignTo(17, 8, 1) = 17 729*523fa7a6SAndroid Build Coastguard Worker /// alignTo(~0LL, 8, 3) = 3 730*523fa7a6SAndroid Build Coastguard Worker /// alignTo(321, 255, 42) = 552 731*523fa7a6SAndroid Build Coastguard Worker /// \endcode 732*523fa7a6SAndroid Build Coastguard Worker inline uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew = 0) { 733*523fa7a6SAndroid Build Coastguard Worker assert(Align != 0u && "Align can't be 0."); 734*523fa7a6SAndroid Build Coastguard Worker Skew %= Align; 735*523fa7a6SAndroid Build Coastguard Worker return (Value + Align - 1 - Skew) / Align * Align + Skew; 736*523fa7a6SAndroid Build Coastguard Worker } 737*523fa7a6SAndroid Build Coastguard Worker 738*523fa7a6SAndroid Build Coastguard Worker /// Returns the next integer (mod 2**64) that is greater than or equal to 739*523fa7a6SAndroid Build Coastguard Worker /// \p Value and is a multiple of \c Align. \c Align must be non-zero. 740*523fa7a6SAndroid Build Coastguard Worker template <uint64_t Align> 741*523fa7a6SAndroid Build Coastguard Worker constexpr inline uint64_t alignTo(uint64_t Value) { 742*523fa7a6SAndroid Build Coastguard Worker static_assert(Align != 0u, "Align must be non-zero"); 743*523fa7a6SAndroid Build Coastguard Worker return (Value + Align - 1) / Align * Align; 744*523fa7a6SAndroid Build Coastguard Worker } 745*523fa7a6SAndroid Build Coastguard Worker 746*523fa7a6SAndroid Build Coastguard Worker /// Returns the integer ceil(Numerator / Denominator). 747*523fa7a6SAndroid Build Coastguard Worker inline uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator) { 748*523fa7a6SAndroid Build Coastguard Worker return alignTo(Numerator, Denominator) / Denominator; 749*523fa7a6SAndroid Build Coastguard Worker } 750*523fa7a6SAndroid Build Coastguard Worker 751*523fa7a6SAndroid Build Coastguard Worker /// \c alignTo for contexts where a constant expression is required. 752*523fa7a6SAndroid Build Coastguard Worker /// \sa alignTo 753*523fa7a6SAndroid Build Coastguard Worker /// 754*523fa7a6SAndroid Build Coastguard Worker /// \todo FIXME: remove when \c constexpr becomes really \c constexpr 755*523fa7a6SAndroid Build Coastguard Worker template <uint64_t Align> 756*523fa7a6SAndroid Build Coastguard Worker struct AlignTo { 757*523fa7a6SAndroid Build Coastguard Worker static_assert(Align != 0u, "Align must be non-zero"); 758*523fa7a6SAndroid Build Coastguard Worker template <uint64_t Value> 759*523fa7a6SAndroid Build Coastguard Worker struct from_value { 760*523fa7a6SAndroid Build Coastguard Worker static const uint64_t value = (Value + Align - 1) / Align * Align; 761*523fa7a6SAndroid Build Coastguard Worker }; 762*523fa7a6SAndroid Build Coastguard Worker }; 763*523fa7a6SAndroid Build Coastguard Worker 764*523fa7a6SAndroid Build Coastguard Worker /// Returns the largest uint64_t less than or equal to \p Value and is 765*523fa7a6SAndroid Build Coastguard Worker /// \p Skew mod \p Align. \p Align must be non-zero 766*523fa7a6SAndroid Build Coastguard Worker inline uint64_t alignDown(uint64_t Value, uint64_t Align, uint64_t Skew = 0) { 767*523fa7a6SAndroid Build Coastguard Worker assert(Align != 0u && "Align can't be 0."); 768*523fa7a6SAndroid Build Coastguard Worker Skew %= Align; 769*523fa7a6SAndroid Build Coastguard Worker return (Value - Skew) / Align * Align + Skew; 770*523fa7a6SAndroid Build Coastguard Worker } 771*523fa7a6SAndroid Build Coastguard Worker 772*523fa7a6SAndroid Build Coastguard Worker /// Returns the offset to the next integer (mod 2**64) that is greater than 773*523fa7a6SAndroid Build Coastguard Worker /// or equal to \p Value and is a multiple of \p Align. \p Align must be 774*523fa7a6SAndroid Build Coastguard Worker /// non-zero. 775*523fa7a6SAndroid Build Coastguard Worker inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) { 776*523fa7a6SAndroid Build Coastguard Worker return alignTo(Value, Align) - Value; 777*523fa7a6SAndroid Build Coastguard Worker } 778*523fa7a6SAndroid Build Coastguard Worker 779*523fa7a6SAndroid Build Coastguard Worker /// Sign-extend the number in the bottom B bits of X to a 32-bit integer. 780*523fa7a6SAndroid Build Coastguard Worker /// Requires 0 < B <= 32. 781*523fa7a6SAndroid Build Coastguard Worker template <unsigned B> 782*523fa7a6SAndroid Build Coastguard Worker constexpr inline int32_t SignExtend32(uint32_t X) { 783*523fa7a6SAndroid Build Coastguard Worker static_assert(B > 0, "Bit width can't be 0."); 784*523fa7a6SAndroid Build Coastguard Worker static_assert(B <= 32, "Bit width out of range."); 785*523fa7a6SAndroid Build Coastguard Worker return int32_t(X << (32 - B)) >> (32 - B); 786*523fa7a6SAndroid Build Coastguard Worker } 787*523fa7a6SAndroid Build Coastguard Worker 788*523fa7a6SAndroid Build Coastguard Worker /// Sign-extend the number in the bottom B bits of X to a 32-bit integer. 789*523fa7a6SAndroid Build Coastguard Worker /// Requires 0 < B < 32. 790*523fa7a6SAndroid Build Coastguard Worker inline int32_t SignExtend32(uint32_t X, unsigned B) { 791*523fa7a6SAndroid Build Coastguard Worker assert(B > 0 && "Bit width can't be 0."); 792*523fa7a6SAndroid Build Coastguard Worker assert(B <= 32 && "Bit width out of range."); 793*523fa7a6SAndroid Build Coastguard Worker return int32_t(X << (32 - B)) >> (32 - B); 794*523fa7a6SAndroid Build Coastguard Worker } 795*523fa7a6SAndroid Build Coastguard Worker 796*523fa7a6SAndroid Build Coastguard Worker /// Sign-extend the number in the bottom B bits of X to a 64-bit integer. 797*523fa7a6SAndroid Build Coastguard Worker /// Requires 0 < B < 64. 798*523fa7a6SAndroid Build Coastguard Worker template <unsigned B> 799*523fa7a6SAndroid Build Coastguard Worker constexpr inline int64_t SignExtend64(uint64_t x) { 800*523fa7a6SAndroid Build Coastguard Worker static_assert(B > 0, "Bit width can't be 0."); 801*523fa7a6SAndroid Build Coastguard Worker static_assert(B <= 64, "Bit width out of range."); 802*523fa7a6SAndroid Build Coastguard Worker return int64_t(x << (64 - B)) >> (64 - B); 803*523fa7a6SAndroid Build Coastguard Worker } 804*523fa7a6SAndroid Build Coastguard Worker 805*523fa7a6SAndroid Build Coastguard Worker /// Sign-extend the number in the bottom B bits of X to a 64-bit integer. 806*523fa7a6SAndroid Build Coastguard Worker /// Requires 0 < B < 64. 807*523fa7a6SAndroid Build Coastguard Worker inline int64_t SignExtend64(uint64_t X, unsigned B) { 808*523fa7a6SAndroid Build Coastguard Worker assert(B > 0 && "Bit width can't be 0."); 809*523fa7a6SAndroid Build Coastguard Worker assert(B <= 64 && "Bit width out of range."); 810*523fa7a6SAndroid Build Coastguard Worker return int64_t(X << (64 - B)) >> (64 - B); 811*523fa7a6SAndroid Build Coastguard Worker } 812*523fa7a6SAndroid Build Coastguard Worker 813*523fa7a6SAndroid Build Coastguard Worker /// Subtract two unsigned integers, X and Y, of type T and return the absolute 814*523fa7a6SAndroid Build Coastguard Worker /// value of the result. 815*523fa7a6SAndroid Build Coastguard Worker template <typename T> 816*523fa7a6SAndroid Build Coastguard Worker typename std::enable_if<std::is_unsigned<T>::value, T>::type AbsoluteDifference( 817*523fa7a6SAndroid Build Coastguard Worker T X, 818*523fa7a6SAndroid Build Coastguard Worker T Y) { 819*523fa7a6SAndroid Build Coastguard Worker return std::max(X, Y) - std::min(X, Y); 820*523fa7a6SAndroid Build Coastguard Worker } 821*523fa7a6SAndroid Build Coastguard Worker 822*523fa7a6SAndroid Build Coastguard Worker /// Add two unsigned integers, X and Y, of type T. Clamp the result to the 823*523fa7a6SAndroid Build Coastguard Worker /// maximum representable value of T on overflow. ResultOverflowed indicates if 824*523fa7a6SAndroid Build Coastguard Worker /// the result is larger than the maximum representable value of type T. 825*523fa7a6SAndroid Build Coastguard Worker template <typename T> 826*523fa7a6SAndroid Build Coastguard Worker typename std::enable_if<std::is_unsigned<T>::value, T>::type SaturatingAdd( 827*523fa7a6SAndroid Build Coastguard Worker T X, 828*523fa7a6SAndroid Build Coastguard Worker T Y, 829*523fa7a6SAndroid Build Coastguard Worker bool* ResultOverflowed = nullptr) { 830*523fa7a6SAndroid Build Coastguard Worker bool Dummy; 831*523fa7a6SAndroid Build Coastguard Worker bool& Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; 832*523fa7a6SAndroid Build Coastguard Worker // Hacker's Delight, p. 29 833*523fa7a6SAndroid Build Coastguard Worker T Z = X + Y; 834*523fa7a6SAndroid Build Coastguard Worker Overflowed = (Z < X || Z < Y); 835*523fa7a6SAndroid Build Coastguard Worker if (Overflowed) 836*523fa7a6SAndroid Build Coastguard Worker return std::numeric_limits<T>::max(); 837*523fa7a6SAndroid Build Coastguard Worker else 838*523fa7a6SAndroid Build Coastguard Worker return Z; 839*523fa7a6SAndroid Build Coastguard Worker } 840*523fa7a6SAndroid Build Coastguard Worker 841*523fa7a6SAndroid Build Coastguard Worker /// Multiply two unsigned integers, X and Y, of type T. Clamp the result to the 842*523fa7a6SAndroid Build Coastguard Worker /// maximum representable value of T on overflow. ResultOverflowed indicates if 843*523fa7a6SAndroid Build Coastguard Worker /// the result is larger than the maximum representable value of type T. 844*523fa7a6SAndroid Build Coastguard Worker template <typename T> 845*523fa7a6SAndroid Build Coastguard Worker typename std::enable_if<std::is_unsigned<T>::value, T>::type SaturatingMultiply( 846*523fa7a6SAndroid Build Coastguard Worker T X, 847*523fa7a6SAndroid Build Coastguard Worker T Y, 848*523fa7a6SAndroid Build Coastguard Worker bool* ResultOverflowed = nullptr) { 849*523fa7a6SAndroid Build Coastguard Worker bool Dummy; 850*523fa7a6SAndroid Build Coastguard Worker bool& Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; 851*523fa7a6SAndroid Build Coastguard Worker 852*523fa7a6SAndroid Build Coastguard Worker // Hacker's Delight, p. 30 has a different algorithm, but we don't use that 853*523fa7a6SAndroid Build Coastguard Worker // because it fails for uint16_t (where multiplication can have undefined 854*523fa7a6SAndroid Build Coastguard Worker // behavior due to promotion to int), and requires a division in addition 855*523fa7a6SAndroid Build Coastguard Worker // to the multiplication. 856*523fa7a6SAndroid Build Coastguard Worker 857*523fa7a6SAndroid Build Coastguard Worker Overflowed = false; 858*523fa7a6SAndroid Build Coastguard Worker 859*523fa7a6SAndroid Build Coastguard Worker // Log2(Z) would be either Log2Z or Log2Z + 1. 860*523fa7a6SAndroid Build Coastguard Worker // Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z 861*523fa7a6SAndroid Build Coastguard Worker // will necessarily be less than Log2Max as desired. 862*523fa7a6SAndroid Build Coastguard Worker int Log2Z = Log2_64(X) + Log2_64(Y); 863*523fa7a6SAndroid Build Coastguard Worker const T Max = std::numeric_limits<T>::max(); 864*523fa7a6SAndroid Build Coastguard Worker int Log2Max = Log2_64(Max); 865*523fa7a6SAndroid Build Coastguard Worker if (Log2Z < Log2Max) { 866*523fa7a6SAndroid Build Coastguard Worker return X * Y; 867*523fa7a6SAndroid Build Coastguard Worker } 868*523fa7a6SAndroid Build Coastguard Worker if (Log2Z > Log2Max) { 869*523fa7a6SAndroid Build Coastguard Worker Overflowed = true; 870*523fa7a6SAndroid Build Coastguard Worker return Max; 871*523fa7a6SAndroid Build Coastguard Worker } 872*523fa7a6SAndroid Build Coastguard Worker 873*523fa7a6SAndroid Build Coastguard Worker // We're going to use the top bit, and maybe overflow one 874*523fa7a6SAndroid Build Coastguard Worker // bit past it. Multiply all but the bottom bit then add 875*523fa7a6SAndroid Build Coastguard Worker // that on at the end. 876*523fa7a6SAndroid Build Coastguard Worker T Z = (X >> 1) * Y; 877*523fa7a6SAndroid Build Coastguard Worker if (Z & ~(Max >> 1)) { 878*523fa7a6SAndroid Build Coastguard Worker Overflowed = true; 879*523fa7a6SAndroid Build Coastguard Worker return Max; 880*523fa7a6SAndroid Build Coastguard Worker } 881*523fa7a6SAndroid Build Coastguard Worker Z <<= 1; 882*523fa7a6SAndroid Build Coastguard Worker if (X & 1) 883*523fa7a6SAndroid Build Coastguard Worker return SaturatingAdd(Z, Y, ResultOverflowed); 884*523fa7a6SAndroid Build Coastguard Worker 885*523fa7a6SAndroid Build Coastguard Worker return Z; 886*523fa7a6SAndroid Build Coastguard Worker } 887*523fa7a6SAndroid Build Coastguard Worker 888*523fa7a6SAndroid Build Coastguard Worker /// Multiply two unsigned integers, X and Y, and add the unsigned integer, A to 889*523fa7a6SAndroid Build Coastguard Worker /// the product. Clamp the result to the maximum representable value of T on 890*523fa7a6SAndroid Build Coastguard Worker /// overflow. ResultOverflowed indicates if the result is larger than the 891*523fa7a6SAndroid Build Coastguard Worker /// maximum representable value of type T. 892*523fa7a6SAndroid Build Coastguard Worker template <typename T> 893*523fa7a6SAndroid Build Coastguard Worker typename std::enable_if<std::is_unsigned<T>::value, T>::type 894*523fa7a6SAndroid Build Coastguard Worker SaturatingMultiplyAdd(T X, T Y, T A, bool* ResultOverflowed = nullptr) { 895*523fa7a6SAndroid Build Coastguard Worker bool Dummy; 896*523fa7a6SAndroid Build Coastguard Worker bool& Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; 897*523fa7a6SAndroid Build Coastguard Worker 898*523fa7a6SAndroid Build Coastguard Worker T Product = SaturatingMultiply(X, Y, &Overflowed); 899*523fa7a6SAndroid Build Coastguard Worker if (Overflowed) 900*523fa7a6SAndroid Build Coastguard Worker return Product; 901*523fa7a6SAndroid Build Coastguard Worker 902*523fa7a6SAndroid Build Coastguard Worker return SaturatingAdd(A, Product, &Overflowed); 903*523fa7a6SAndroid Build Coastguard Worker } 904*523fa7a6SAndroid Build Coastguard Worker 905*523fa7a6SAndroid Build Coastguard Worker /// Use this rather than HUGE_VALF; the latter causes warnings on MSVC. 906*523fa7a6SAndroid Build Coastguard Worker extern const float huge_valf; 907*523fa7a6SAndroid Build Coastguard Worker } // namespace llvm 908*523fa7a6SAndroid Build Coastguard Worker } // namespace executorch 909