aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Huang <huangs@chromium.org>2019-03-15 21:08:23 +0000
committerCopybara-Service <copybara-worker@google.com>2021-07-25 20:52:03 -0700
commit156a6f21e644f2186e7ed2ef72df76939f58931c (patch)
treeaad3f272a02c70f3bc8c8343d5c6c13524e3c14e
parent8afcc01dc2db45c4c4b3fe8839f194fafb581298 (diff)
downloadzucchini-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.h14
-rw-r--r--algorithm_unittest.cc27
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;