1 // Copyright 2019 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "util.h" 6 7 #include <assert.h> 8 9 // 10 // 11 // 12 13 #if defined(_MSC_VER) && !defined(__clang__) 14 15 #include <intrin.h> 16 17 #endif 18 19 // 20 // 21 // 22 23 bool is_pow2_u32(uint32_t n)24is_pow2_u32(uint32_t n) 25 { 26 return n && !(n & (n - 1)); 27 } 28 29 // 30 // 31 // 32 33 uint32_t pow2_ru_u32(uint32_t n)34pow2_ru_u32(uint32_t n) 35 { 36 assert(n <= 0x80000000U); 37 38 n--; 39 n |= n >> 1; 40 n |= n >> 2; 41 n |= n >> 4; 42 n |= n >> 8; 43 n |= n >> 16; 44 n++; 45 46 return n; 47 } 48 49 // 50 // 51 // 52 53 uint32_t pow2_rd_u32(uint32_t n)54pow2_rd_u32(uint32_t n) 55 { 56 assert(n > 0); 57 58 return 1u << msb_idx_u32(n); 59 } 60 61 // 62 // ASSUMES NON-ZERO 63 // 64 65 uint32_t msb_idx_u32(uint32_t n)66msb_idx_u32(uint32_t n) 67 { 68 assert(n > 0); 69 #if defined(_MSC_VER) && !defined(__clang__) 70 71 uint32_t index; 72 73 _BitScanReverse((unsigned long *)&index, n); 74 75 return index; 76 77 #elif defined(__GNUC__) 78 79 return __builtin_clz(n) ^ 31; 80 81 #else 82 83 #error "No msb_index()" 84 85 #endif 86 } 87 88 // 89 // 90 // 91