aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgia Kouveli <georgia.kouveli@arm.com>2017-05-03 17:23:47 +0100
committerGeorgia Kouveli <georgia.kouveli@arm.com>2017-05-15 18:05:28 +0000
commitbbd09d6eed4e2aa639adabcc3b304a20fe0c8a42 (patch)
treeeba6ee04f574ef939351d327711fe2c8fad404c0
parent275c9d477d5bb717ac48f29db4ed153495be5ad3 (diff)
Assume power of two alignment for AlignUp and AlignDown.
Change-Id: Ic396b3089447c34f40c1fd2986b888237729711b
-rw-r--r--src/globals-vixl.h13
-rw-r--r--src/utils-vixl.h32
2 files changed, 30 insertions, 15 deletions
diff --git a/src/globals-vixl.h b/src/globals-vixl.h
index beada9eb..bcb09936 100644
--- a/src/globals-vixl.h
+++ b/src/globals-vixl.h
@@ -71,6 +71,19 @@ const int MBytes = 1024 * KBytes;
const int kBitsPerByte = 8;
+template <int SizeInBytes>
+struct Unsigned;
+
+template <>
+struct Unsigned<4> {
+ typedef uint32_t type;
+};
+
+template <>
+struct Unsigned<8> {
+ typedef uint64_t type;
+};
+
} // namespace vixl
// Detect the host's pointer size.
diff --git a/src/utils-vixl.h b/src/utils-vixl.h
index 947e09c8..4c7bea02 100644
--- a/src/utils-vixl.h
+++ b/src/utils-vixl.h
@@ -472,40 +472,42 @@ bool IsWordAligned(T pointer) {
return IsAligned<4>(pointer);
}
-// Increment a pointer (up to 64 bits) until it has the specified alignment.
+// Increment a pointer until it has the specified alignment. The alignment must
+// be a power of two.
template <class T>
-T AlignUp(T pointer, size_t alignment) {
+T AlignUp(T pointer, typename Unsigned<sizeof(T)>::type alignment) {
+ VIXL_ASSERT(IsPowerOf2(alignment));
// Use C-style casts to get static_cast behaviour for integral types (T), and
// reinterpret_cast behaviour for other types.
- uint64_t pointer_raw = (uint64_t)pointer;
+ typename Unsigned<sizeof(T)>::type pointer_raw =
+ (typename Unsigned<sizeof(T)>::type)pointer;
VIXL_STATIC_ASSERT(sizeof(pointer) <= sizeof(pointer_raw));
- size_t align_step = (alignment - pointer_raw) % alignment;
- VIXL_ASSERT((pointer_raw + align_step) % alignment == 0);
-
- T result = (T)(pointer_raw + align_step);
-
+ size_t mask = alignment - 1;
+ T result = (T)((pointer_raw + mask) & ~mask);
VIXL_ASSERT(result >= pointer);
return result;
}
-// Decrement a pointer (up to 64 bits) until it has the specified alignment.
+// Decrement a pointer until it has the specified alignment. The alignment must
+// be a power of two.
template <class T>
-T AlignDown(T pointer, size_t alignment) {
+T AlignDown(T pointer, typename Unsigned<sizeof(T)>::type alignment) {
+ VIXL_ASSERT(IsPowerOf2(alignment));
// Use C-style casts to get static_cast behaviour for integral types (T), and
// reinterpret_cast behaviour for other types.
- uint64_t pointer_raw = (uint64_t)pointer;
+ typename Unsigned<sizeof(T)>::type pointer_raw =
+ (typename Unsigned<sizeof(T)>::type)pointer;
VIXL_STATIC_ASSERT(sizeof(pointer) <= sizeof(pointer_raw));
- size_t align_step = pointer_raw % alignment;
- VIXL_ASSERT((pointer_raw - align_step) % alignment == 0);
-
- return (T)(pointer_raw - align_step);
+ size_t mask = alignment - 1;
+ return (T)(pointer_raw & ~mask);
}
+
template <typename T>
inline T ExtractBit(T value, unsigned bit) {
return (value >> bit) & T(1);