diff options
author | Georgia Kouveli <georgia.kouveli@arm.com> | 2017-05-03 17:23:47 +0100 |
---|---|---|
committer | Georgia Kouveli <georgia.kouveli@arm.com> | 2017-05-15 18:05:28 +0000 |
commit | bbd09d6eed4e2aa639adabcc3b304a20fe0c8a42 (patch) | |
tree | eba6ee04f574ef939351d327711fe2c8fad404c0 | |
parent | 275c9d477d5bb717ac48f29db4ed153495be5ad3 (diff) |
Assume power of two alignment for AlignUp and AlignDown.
Change-Id: Ic396b3089447c34f40c1fd2986b888237729711b
-rw-r--r-- | src/globals-vixl.h | 13 | ||||
-rw-r--r-- | src/utils-vixl.h | 32 |
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); |