blob: 98af437869105c56a6985e1c188354874803f6e0 [file] [log] [blame]
// Copyright 2011 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "syzygy/common/align.h"
#include "base/logging.h"
namespace common {
namespace {
template <typename T>
uint8 CountTrailingZeros(T value) {
uint8 trailing_zeros = 0;
// Sets the trailing zeros to one and sets the other bits to zero.
// This is inspired from the code on this page:
// http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear
value = (value ^ (value - 1)) >> 1;
for (; value > 0; trailing_zeros++)
value >>= 1;
return trailing_zeros;
}
} // namespace
bool IsPowerOfTwo(size_t value) {
return value != 0 && (value & (value - 1)) == 0;
}
size_t AlignUp(size_t value, size_t alignment) {
DCHECK_NE(0U, alignment);
if (IsPowerOfTwo(alignment)) {
return (value + alignment - 1) & ~(alignment - 1);
} else {
return ((value + alignment - 1) / alignment) * alignment;
}
}
size_t AlignDown(size_t value, size_t alignment) {
DCHECK_NE(0U, alignment);
if (IsPowerOfTwo(alignment)) {
return value & ~(alignment - 1);
} else {
return (value / alignment) * alignment;
}
}
bool IsAligned(size_t value, size_t alignment) {
return AlignDown(value, alignment) == value;
}
size_t GetAlignment(size_t value) {
return 1 << CountTrailingZeros(value);
}
bool IsPowerOfTwo64(uint64 value) {
return value != 0 && (value & (value - 1)) == 0;
}
uint64 AlignUp64(uint64 value, uint64 alignment) {
DCHECK_NE(0U, alignment);
if (IsPowerOfTwo64(alignment)) {
return (value + alignment - 1) & ~(alignment - 1);
} else {
return ((value + alignment - 1) / alignment) * alignment;
}
}
uint64 AlignDown64(uint64 value, uint64 alignment) {
DCHECK_NE(0U, alignment);
if (IsPowerOfTwo64(alignment)) {
return value & ~(alignment - 1);
} else {
return (value / alignment) * alignment;
}
}
bool IsAligned64(uint64 value, uint64 alignment) {
return AlignDown64(value, alignment) == value;
}
uint64 GetAlignment64(uint64 value) {
return 1ULL << CountTrailingZeros(value);
}
} // namespace common