• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)24 is_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)34 pow2_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)54 pow2_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)66 msb_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