1 : // Copyright 2011 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/common/align.h"
16 :
17 : #include "base/logging.h"
18 :
19 : namespace common {
20 :
21 : namespace {
22 :
23 : template <typename T>
24 E : uint8 CountTrailingZeros(T value) {
25 E : uint8 trailing_zeros = 0;
26 :
27 : // Sets the trailing zeros to one and sets the other bits to zero.
28 : // This is inspired from the code on this page:
29 : // http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear
30 E : value = (value ^ (value - 1)) >> 1;
31 :
32 E : for (; value > 0; trailing_zeros++)
33 E : value >>= 1;
34 :
35 E : return trailing_zeros;
36 E : }
37 :
38 : } // namespace
39 :
40 E : bool IsPowerOfTwo(size_t value) {
41 E : return value != 0 && (value & (value - 1)) == 0;
42 E : }
43 :
44 E : size_t AlignUp(size_t value, size_t alignment) {
45 E : DCHECK_NE(0U, alignment);
46 :
47 E : if (IsPowerOfTwo(alignment)) {
48 E : return (value + alignment - 1) & ~(alignment - 1);
49 i : } else {
50 E : return ((value + alignment - 1) / alignment) * alignment;
51 : }
52 E : }
53 :
54 E : size_t AlignDown(size_t value, size_t alignment) {
55 E : DCHECK_NE(0U, alignment);
56 :
57 E : if (IsPowerOfTwo(alignment)) {
58 E : return value & ~(alignment - 1);
59 i : } else {
60 E : return (value / alignment) * alignment;
61 : }
62 E : }
63 :
64 E : bool IsAligned(size_t value, size_t alignment) {
65 E : return AlignDown(value, alignment) == value;
66 E : }
67 :
68 E : size_t GetAlignment(size_t value) {
69 E : return 1 << CountTrailingZeros(value);
70 E : }
71 :
72 E : bool IsPowerOfTwo64(uint64 value) {
73 E : return value != 0 && (value & (value - 1)) == 0;
74 E : }
75 :
76 E : uint64 AlignUp64(uint64 value, uint64 alignment) {
77 E : DCHECK_NE(0U, alignment);
78 :
79 E : if (IsPowerOfTwo64(alignment)) {
80 E : return (value + alignment - 1) & ~(alignment - 1);
81 i : } else {
82 E : return ((value + alignment - 1) / alignment) * alignment;
83 : }
84 E : }
85 :
86 E : uint64 AlignDown64(uint64 value, uint64 alignment) {
87 E : DCHECK_NE(0U, alignment);
88 :
89 E : if (IsPowerOfTwo64(alignment)) {
90 E : return value & ~(alignment - 1);
91 i : } else {
92 E : return (value / alignment) * alignment;
93 : }
94 E : }
95 :
96 E : bool IsAligned64(uint64 value, uint64 alignment) {
97 E : return AlignDown64(value, alignment) == value;
98 E : }
99 :
100 E : uint64 GetAlignment64(uint64 value) {
101 E : return 1ULL << CountTrailingZeros(value);
102 E : }
103 :
104 : } // namespace common
|