diff options
author | Samuel Huang <huangs@chromium.org> | 2019-03-15 21:08:23 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2021-07-25 20:52:03 -0700 |
commit | 156a6f21e644f2186e7ed2ef72df76939f58931c (patch) | |
tree | aad3f272a02c70f3bc8c8343d5c6c13524e3c14e | |
parent | 8afcc01dc2db45c4c4b3fe8839f194fafb581298 (diff) | |
download | zucchini-156a6f21e644f2186e7ed2ef72df76939f58931c.tar.gz |
[Zucchini] Add helpers for 2 byte and 4 byte alignment.
This CL adds specialized versions of AlignCeil():
{IncrementForAlignCeil2(), IncrementForAlignCeil4()}.
Given a value to be aligned, these functions return an increment that
the caller can add to the given value to cause alignment. This scheme
admits iterator alignment. e.g., by:
aligned_it = it + IncrementForAlignCeil4(it - base_it);
These functions will be used by code to add ARM support.
Bug: 918867
Change-Id: I6da038a748a29cde82e4c82e597455644213abd9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524920
Reviewed-by: Samuel Huang <huangs@chromium.org>
Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
Commit-Queue: Samuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641279}
NOKEYCHECK=True
GitOrigin-RevId: dc2c91d1d1cf5aeac19b25210e470909f175b160
-rw-r--r-- | algorithm.h | 14 | ||||
-rw-r--r-- | algorithm_unittest.cc | 27 |
2 files changed, 41 insertions, 0 deletions
diff --git a/algorithm.h b/algorithm.h index 463aca3..898859f 100644 --- a/algorithm.h +++ b/algorithm.h @@ -53,6 +53,20 @@ constexpr T AlignCeil(T x, T m) { return T((x + m - 1) / m) * m; } +// Specialized alignment helpers that returns the increment to |pos| to get the +// next n-aligned value, where n is in {2, 4}. This is useful for aligning +// iterators relative to a base iterator using: +// it += IncrementForAlignCeil2(it - base); +template <class T> +inline int IncrementForAlignCeil2(T pos) { + return static_cast<int>(pos & 1); // Optimized from (-pos) & 1. +} + +template <class T> +inline int IncrementForAlignCeil4(T pos) { + return static_cast<int>((-pos) & 3); +} + // Sorts values in |container| and removes duplicates. template <class T> void SortAndUniquify(std::vector<T>* container) { diff --git a/algorithm_unittest.cc b/algorithm_unittest.cc index a395b1e..ad5b9b8 100644 --- a/algorithm_unittest.cc +++ b/algorithm_unittest.cc @@ -145,6 +145,33 @@ TEST(AlgorithmTest, AlignCeil) { EXPECT_EQ(33U, AlignCeil<uint32_t>(23U, 11U)); } +TEST(AlgorithmTest, IncrementForAlignCeil) { + struct TestCase { + int exp; // Increment to |pos| to get the next nearest aligned value. + int pos; + }; + TestCase kTestCases2[] = { + {0, 0}, {1, 1}, {0, 2}, {1, 3}, {0, 4}, {1, 5}, + {1, 97}, {0, 98}, {1, 99}, {0, 100}, {1, -1}, {0, -2}, + {1, -101}, {0, -100}, {1, -99}, {0, -98}, {1, -97}, {0, -96}, + }; + for (const auto& test_case : kTestCases2) { + EXPECT_EQ(test_case.exp, IncrementForAlignCeil2<int32_t>(test_case.pos)); + if (test_case.pos >= 0) + EXPECT_EQ(test_case.exp, IncrementForAlignCeil2<uint32_t>(test_case.pos)); + } + TestCase kTestCases4[] = { + {0, 0}, {3, 1}, {2, 2}, {1, 3}, {0, 4}, {3, 5}, + {3, 97}, {2, 98}, {1, 99}, {0, 100}, {1, -1}, {2, -2}, + {1, -101}, {0, -100}, {3, -99}, {2, -98}, {1, -97}, {0, -96}, + }; + for (const auto& test_case : kTestCases4) { + EXPECT_EQ(test_case.exp, IncrementForAlignCeil4<int32_t>(test_case.pos)); + if (test_case.pos >= 0) + EXPECT_EQ(test_case.exp, IncrementForAlignCeil4<uint32_t>(test_case.pos)); + } +} + TEST(AlgorithmTest, GetBit) { // 0xC5 = 0b1100'0101. constexpr uint8_t v = 0xC5; |