Skip to content

Commit 20e7f42

Browse files
committed
cleanup
1 parent 7d8379f commit 20e7f42

File tree

2 files changed

+119
-127
lines changed

2 files changed

+119
-127
lines changed

inc/zoo/swar/SWAR.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,24 @@ struct SWAR {
7171

7272
constexpr T value() const noexcept { return m_v; }
7373

74-
constexpr static T baseFromLaneLiterals(std::initializer_list<T> args) noexcept {
74+
template<std::size_t N>
75+
constexpr static T baseFromLaneLiterals(const T(&args)[N]) {
76+
static_assert(N == Lanes, "Wrong number of lanes");
7577
T result = 0;
7678
for (auto arg: args) {
7779
result = (result << NBits) | arg;
7880
}
7981
return result;
8082
}
8183

82-
constexpr static SWAR fromLaneLiterals(std::initializer_list<T> args) noexcept {
83-
return SWAR(baseFromLaneLiterals(args));
84+
template<std::size_t N>
85+
constexpr static SWAR fromLaneLiterals(const T(&args)[N]) {
86+
return SWAR{baseFromLaneLiterals(args)};
8487
}
8588

8689

90+
91+
8792
#define SWAR_UNARY_OPERATORS_X_LIST \
8893
X(SWAR, ~)
8994
//constexpr SWAR operator~() const noexcept { return SWAR{~m_v}; }
@@ -508,4 +513,9 @@ static_assert(
508513
0x0706050403020100ull
509514
);
510515

516+
517+
511518
}}
519+
520+
521+
static_assert(zoo::swar::SWAR<8, zoo::swar::u32>::baseFromLaneLiterals({0, 0, 0, 0}) == 0);

test/swar/BasicOperations.cpp

Lines changed: 106 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
#include <type_traits>
66

7-
87
using namespace zoo;
98
using namespace zoo::swar;
109

@@ -21,7 +20,8 @@ constexpr auto Doubled =
2120

2221
static_assert(0x090B0D0F == Doubled.even.value());
2322
static_assert(0x080A0C0E == Doubled.odd.value());
24-
static_assert(PrecisionFixtureTest == halvePrecision(Doubled.even, Doubled.odd).value());
23+
static_assert(PrecisionFixtureTest ==
24+
halvePrecision(Doubled.even, Doubled.odd).value());
2525

2626
constexpr SWAR<8, u32> Micand{0x5030201};
2727
constexpr SWAR<8, u32> Mplier{0xA050301};
@@ -33,32 +33,28 @@ constexpr SWAR<8, u32> Mplier{0xA050301};
3333
// 1*1 = 1
3434
constexpr auto Expected = 0x320F0601;
3535

36-
static_assert(
37-
Expected == multiplication_OverflowUnsafe(Micand, Mplier).value()
38-
);
36+
static_assert(Expected ==
37+
multiplication_OverflowUnsafe(Micand, Mplier).value());
3938
static_assert(
4039
0x320F0601 != // intentionally use a too-small bit count
41-
multiplication_OverflowUnsafe_SpecificBitCount<3>(Micand, Mplier).value()
42-
);
43-
44-
static_assert(0b00000010000000110000010100000110 == 0x02'03'05'06);
40+
multiplication_OverflowUnsafe_SpecificBitCount<3>(Micand, Mplier).value());
4541

4642
TEST_CASE("Jamie's totally working exponentiation :D") {
47-
constexpr auto base = SWAR<8, u32>::fromLaneLiterals({2, 3, 5, 6});
48-
constexpr auto exponent = SWAR<8, u32>::fromLaneLiterals({7, 0, 2, 3});
49-
constexpr auto expected = SWAR<8, u32>::fromLaneLiterals({128, 1, 25, 216});
50-
constexpr auto actual = exponentiation_OverflowUnsafe(base, exponent);
51-
static_assert(expected.value() == actual.value());
52-
CHECK(expected.value() == actual.value());
43+
using S = SWAR<8, u32>;
44+
constexpr auto base = S::fromLaneLiterals({2, 3, 5, 6});
45+
constexpr auto exponent = S::fromLaneLiterals({7, 0, 2, 3});
46+
constexpr auto expected = S::fromLaneLiterals({128, 1, 25, 216});
47+
constexpr auto actual = exponentiation_OverflowUnsafe(base, exponent);
48+
static_assert(expected.value() == actual.value());
49+
CHECK(expected.value() == actual.value());
5350
}
5451

55-
}
52+
} // namespace Multiplication
5653

57-
#define HE(nbits, t, v0, v1) \
58-
static_assert(horizontalEquality<nbits, t>(\
59-
SWAR<nbits, t>(v0),\
60-
SWAR<nbits, t>(meta::BitmaskMaker<t, v1, nbits>::value)\
61-
));
54+
#define HE(nbits, t, v0, v1) \
55+
static_assert(horizontalEquality<nbits, t>( \
56+
SWAR<nbits, t>(v0), \
57+
SWAR<nbits, t>(meta::BitmaskMaker<t, v1, nbits>::value)));
6258
HE(8, u64, 0x0808'0808'0808'0808, 0x8);
6359
HE(4, u64, 0x1111'1111'1111'1111, 0x1);
6460
HE(3, u64, 0xFFFF'FFFF'FFFF'FFFF, 0x7);
@@ -69,47 +65,42 @@ HE(2, u8, 0xAA, 0x2);
6965
#undef HE
7066

7167
TEST_CASE("Old version", "[deprecated][swar]") {
72-
SWAR<8, u32> Micand{0x5030201};
73-
SWAR<8, u32> Mplier{0xA050301};
74-
auto Expected = 0x320F0601;
75-
auto result =
76-
multiplication_OverflowUnsafe_SpecificBitCount_deprecated<4>(
77-
Micand, Mplier
78-
);
79-
CHECK(Expected == result.value());
68+
SWAR<8, u32> Micand{0x5030201};
69+
SWAR<8, u32> Mplier{0xA050301};
70+
auto Expected = 0x320F0601;
71+
auto result = multiplication_OverflowUnsafe_SpecificBitCount_deprecated<4>(
72+
Micand, Mplier);
73+
CHECK(Expected == result.value());
8074
}
8175

8276
TEST_CASE("Parity", "[swar]") {
83-
// For each nibble, E indicates (E)ven and O (O)dd parities
84-
// EEOEEOOO
85-
auto Examples = 0xFF13A7E4;
86-
SWAR<4, u32> casesBy4{Examples};
87-
SWAR<8, u32> casesBy8{Examples};
88-
auto by4 = parity(casesBy4);
89-
auto by8 = parity(casesBy8);
90-
CHECK(by4.value() == 0x00800888);
91-
CHECK(by8.value() == 0x00808000);
77+
// For each nibble, E indicates (E)ven and O (O)dd parities
78+
// EEOEEOOO
79+
auto Examples = 0xFF13A7E4;
80+
SWAR<4, u32> casesBy4{Examples};
81+
SWAR<8, u32> casesBy8{Examples};
82+
auto by4 = parity(casesBy4);
83+
auto by8 = parity(casesBy8);
84+
CHECK(by4.value() == 0x00800888);
85+
CHECK(by8.value() == 0x00808000);
9286
}
9387

94-
TEST_CASE(
95-
"Isolate",
96-
"[swar]"
97-
) {
98-
for (auto i = 0; i < 63; ++i) {
99-
CHECK(i == isolate<8>(i));
100-
CHECK(i == isolate<8>(0xFF00+i));
101-
CHECK(i == isolate<8>(0xFFFF00+i));
102-
}
103-
for (auto i = 0; i < 31; ++i) {
104-
CHECK(i == isolate<7>(i));
105-
CHECK(i == isolate<7>(0xFF00+i));
106-
CHECK(i == isolate<7>(0xFFFF00+i));
107-
}
108-
for (auto i = 0; i < 31; ++i) {
109-
CHECK(i == isolate<11>(i));
110-
CHECK(i == isolate<11>(0xF800+i));
111-
CHECK(i == isolate<11>(0xFFF800+i));
112-
}
88+
TEST_CASE("Isolate", "[swar]") {
89+
for (auto i = 0; i < 63; ++i) {
90+
CHECK(i == isolate<8>(i));
91+
CHECK(i == isolate<8>(0xFF00 + i));
92+
CHECK(i == isolate<8>(0xFFFF00 + i));
93+
}
94+
for (auto i = 0; i < 31; ++i) {
95+
CHECK(i == isolate<7>(i));
96+
CHECK(i == isolate<7>(0xFF00 + i));
97+
CHECK(i == isolate<7>(0xFFFF00 + i));
98+
}
99+
for (auto i = 0; i < 31; ++i) {
100+
CHECK(i == isolate<11>(i));
101+
CHECK(i == isolate<11>(0xF800 + i));
102+
CHECK(i == isolate<11>(0xFFF800 + i));
103+
}
113104
}
114105

115106
static_assert(1 == popcount<5>(0x100ull));
@@ -122,13 +113,13 @@ static_assert(0x210 == popcount<1>(0x320));
122113
static_assert(0x4321 == popcount<2>(0xF754));
123114
static_assert(0x50004 == popcount<4>(0x3E001122));
124115

125-
static_assert(1 == msbIndex<u64>(1ull<<1));
126-
static_assert(3 == msbIndex<u64>(1ull<<3));
127-
static_assert(5 == msbIndex<u64>(1ull<<5));
128-
static_assert(8 == msbIndex<u64>(1ull<<8));
129-
static_assert(17 == msbIndex<u64>(1ull<<17));
130-
static_assert(30 == msbIndex<u64>(1ull<<30));
131-
static_assert(31 == msbIndex<u64>(1ull<<31));
116+
static_assert(1 == msbIndex<u64>(1ull << 1));
117+
static_assert(3 == msbIndex<u64>(1ull << 3));
118+
static_assert(5 == msbIndex<u64>(1ull << 5));
119+
static_assert(8 == msbIndex<u64>(1ull << 8));
120+
static_assert(17 == msbIndex<u64>(1ull << 17));
121+
static_assert(30 == msbIndex<u64>(1ull << 30));
122+
static_assert(31 == msbIndex<u64>(1ull << 31));
132123

133124
namespace {
134125
using namespace zoo::meta;
@@ -139,7 +130,7 @@ static_assert(0x0808'0808'0808'0808ull == BitmaskMaker<u64, 0x08ull, 8>::value);
139130
static_assert(0x0101'0101'0101'0101ull == BitmaskMaker<u64, 0x01ull, 8>::value);
140131
static_assert(0x0E0E'0E0E'0E0E'0E0Eull == BitmaskMaker<u64, 0x0Eull, 8>::value);
141132
static_assert(0x0303'0303'0303'0303ull == BitmaskMaker<u64, 0x03ull, 8>::value);
142-
}
133+
} // namespace
143134

144135
static_assert(0x00 == clearLSB<u8>(0x80));
145136
static_assert(0x80 == clearLSB<u8>(0xC0));
@@ -227,53 +218,44 @@ static_assert(0x0808'0808 == u32(broadcast<8>(SWAR<8, u32>(0x0000'0008))));
227218
static_assert(0x0B0B'0B0B == u32(broadcast<8>(SWAR<8, u32>(0x0000'000B))));
228219
static_assert(0x0E0E'0E0E == u32(broadcast<8>(SWAR<8, u32>(0x0000'000E))));
229220
static_assert(0x6B6B'6B6B == u32(broadcast<8>(SWAR<8, u32>(0x0000'006B))));
230-
static_assert(0x0808'0808'0808'0808ull == u64(broadcast<8>(SWAR<8, u64>(0x0000'0000'0000'0008ull))));
221+
static_assert(0x0808'0808'0808'0808ull ==
222+
u64(broadcast<8>(SWAR<8, u64>(0x0000'0000'0000'0008ull))));
231223

232-
static_assert(1 == lsbIndex(1<<1));
233-
static_assert(3 == lsbIndex(1<<3));
234-
static_assert(5 == lsbIndex(1<<5));
235-
static_assert(8 == lsbIndex(1<<8));
236-
static_assert(17 == lsbIndex(1<<17));
237-
static_assert(30 == lsbIndex(1<<30));
224+
static_assert(1 == lsbIndex(1 << 1));
225+
static_assert(3 == lsbIndex(1 << 3));
226+
static_assert(5 == lsbIndex(1 << 5));
227+
static_assert(8 == lsbIndex(1 << 8));
228+
static_assert(17 == lsbIndex(1 << 17));
229+
static_assert(30 == lsbIndex(1 << 30));
238230

239231
/*
240232
These tests were not catching errors known to have been present
241-
static_assert(0x80880008 == greaterEqual<3>(SWAR<4, uint32_t>(0x3245'1027)).value());
242-
static_assert(0x88888888 == greaterEqual<0>(SWAR<4, uint32_t>(0x0123'4567)).value());
243-
static_assert(0x88888888 == greaterEqual<0>(SWAR<4, uint32_t>(0x7654'3210)).value());
244-
static_assert(0x00000008 == greaterEqual<7>(SWAR<4, uint32_t>(0x0123'4567)).value());
245-
static_assert(0x80000000 == greaterEqual<7>(SWAR<4, uint32_t>(0x7654'3210)).value());
233+
static_assert(0x80880008 == greaterEqual<3>(SWAR<4,
234+
uint32_t>(0x3245'1027)).value()); static_assert(0x88888888 ==
235+
greaterEqual<0>(SWAR<4, uint32_t>(0x0123'4567)).value());
236+
static_assert(0x88888888 == greaterEqual<0>(SWAR<4,
237+
uint32_t>(0x7654'3210)).value()); static_assert(0x00000008 ==
238+
greaterEqual<7>(SWAR<4, uint32_t>(0x0123'4567)).value());
239+
static_assert(0x80000000 == greaterEqual<7>(SWAR<4,
240+
uint32_t>(0x7654'3210)).value());
246241
*/
247242

248243
// Unusual formatting for easy visual verification.
249-
#define GE_MSB_TEST(left, right, result) static_assert(result== greaterEqual_MSB_off<4, u32>(SWAR<4, u32>(left), SWAR<4, u32>(right)).value());
250-
251-
GE_MSB_TEST(0x1000'0010,
252-
0x0111'1101,
253-
0x8000'0080)
254-
GE_MSB_TEST(0x4333'3343,
255-
0x4444'4444,
256-
0x8000'0080)
257-
GE_MSB_TEST(0x0550'0110,
258-
0x0110'0550,
259-
0x8888'8008)
260-
GE_MSB_TEST(0x4771'1414,
261-
0x4641'1774,
262-
0x8888'8008)
263-
264-
GE_MSB_TEST(0x0123'4567,
265-
0x0000'0000,
266-
0x8888'8888)
267-
GE_MSB_TEST(0x0123'4567,
268-
0x7777'7777,
269-
0x0000'0008)
270-
271-
GE_MSB_TEST(0x0000'0000,
272-
0x0123'4567,
273-
0x8000'0000)
274-
GE_MSB_TEST(0x7777'7777,
275-
0x0123'4567,
276-
0x8888'8888)
244+
#define GE_MSB_TEST(left, right, result) \
245+
static_assert(result == greaterEqual_MSB_off<4, u32>(SWAR<4, u32>(left), \
246+
SWAR<4, u32>(right)) \
247+
.value());
248+
249+
GE_MSB_TEST(0x1000'0010, 0x0111'1101, 0x8000'0080)
250+
GE_MSB_TEST(0x4333'3343, 0x4444'4444, 0x8000'0080)
251+
GE_MSB_TEST(0x0550'0110, 0x0110'0550, 0x8888'8008)
252+
GE_MSB_TEST(0x4771'1414, 0x4641'1774, 0x8888'8008)
253+
254+
GE_MSB_TEST(0x0123'4567, 0x0000'0000, 0x8888'8888)
255+
GE_MSB_TEST(0x0123'4567, 0x7777'7777, 0x0000'0008)
256+
257+
GE_MSB_TEST(0x0000'0000, 0x0123'4567, 0x8000'0000)
258+
GE_MSB_TEST(0x7777'7777, 0x0123'4567, 0x8888'8888)
277259

278260
// 3 bits on msb side, 5 bits on lsb side.
279261
using Lanes = SWARWithSubLanes<5, 3, u32>;
@@ -284,25 +266,25 @@ static constexpr inline u32 allF = broadcast<8>(S8u32(0x0000'00FFul)).value();
284266
static_assert(allF == Lanes(allF).value());
285267
static_assert(0xFFFF'FFFF == Lanes(allF).value());
286268

287-
static_assert(0xFFFF'FFE0 == Lanes(allF).least(0,0).value());
288-
static_assert(0xFFFF'FFE1 == Lanes(allF).least(1,0).value());
289-
static_assert(0xFFFF'E0FF == Lanes(allF).least(0,1).value());
290-
static_assert(0xFFFF'E1FF == Lanes(allF).least(1,1).value());
291-
292-
static_assert(0xFFE0'FFFF == Lanes(allF).least(0,2).value());
293-
static_assert(0xFFE1'FFFF == Lanes(allF).least(1,2).value());
294-
static_assert(0xE0FF'FFFF == Lanes(allF).least(0,3).value());
295-
static_assert(0xE1FF'FFFF == Lanes(allF).least(1,3).value());
296-
297-
static_assert(0xFFFF'FF1F == Lanes(allF).most(0,0).value());
298-
static_assert(0xFFFF'FF3F == Lanes(allF).most(1,0).value());
299-
static_assert(0xFFFF'1FFF == Lanes(allF).most(0,1).value());
300-
static_assert(0xFFFF'3FFF == Lanes(allF).most(1,1).value());
301-
302-
static_assert(0xFF1F'FFFF == Lanes(allF).most(0,2).value());
303-
static_assert(0xFF3F'FFFF == Lanes(allF).most(1,2).value());
304-
static_assert(0x1FFF'FFFF == Lanes(allF).most(0,3).value());
305-
static_assert(0x3FFF'FFFF == Lanes(allF).most(1,3).value());
269+
static_assert(0xFFFF'FFE0 == Lanes(allF).least(0, 0).value());
270+
static_assert(0xFFFF'FFE1 == Lanes(allF).least(1, 0).value());
271+
static_assert(0xFFFF'E0FF == Lanes(allF).least(0, 1).value());
272+
static_assert(0xFFFF'E1FF == Lanes(allF).least(1, 1).value());
273+
274+
static_assert(0xFFE0'FFFF == Lanes(allF).least(0, 2).value());
275+
static_assert(0xFFE1'FFFF == Lanes(allF).least(1, 2).value());
276+
static_assert(0xE0FF'FFFF == Lanes(allF).least(0, 3).value());
277+
static_assert(0xE1FF'FFFF == Lanes(allF).least(1, 3).value());
278+
279+
static_assert(0xFFFF'FF1F == Lanes(allF).most(0, 0).value());
280+
static_assert(0xFFFF'FF3F == Lanes(allF).most(1, 0).value());
281+
static_assert(0xFFFF'1FFF == Lanes(allF).most(0, 1).value());
282+
static_assert(0xFFFF'3FFF == Lanes(allF).most(1, 1).value());
283+
284+
static_assert(0xFF1F'FFFF == Lanes(allF).most(0, 2).value());
285+
static_assert(0xFF3F'FFFF == Lanes(allF).most(1, 2).value());
286+
static_assert(0x1FFF'FFFF == Lanes(allF).most(0, 3).value());
287+
static_assert(0x3FFF'FFFF == Lanes(allF).most(1, 3).value());
306288

307289
static_assert(0x0000'001f == Lanes(all0).least(31, 0).most(0, 0).value());
308290
static_assert(0x0000'1f00 == Lanes(all0).least(31, 1).most(0, 1).value());

0 commit comments

Comments
 (0)