no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / mfbt / tests / TestSIMD.cpp
blob23dc8b01174d712588178dedcd326b577e8dbd87
1 /* -*- Mode: C++; tab-width: 9; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/Assertions.h"
8 #include "mozilla/SIMD.h"
10 using mozilla::SIMD;
12 void TestTinyString() {
13 const char* test = "012\n";
15 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '0', 3) == test + 0x0);
16 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '0', 3) == test + 0x0);
17 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '1', 3) == test + 0x1);
18 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '1', 3) == test + 0x1);
19 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '2', 3) == test + 0x2);
20 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '2', 3) == test + 0x2);
21 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '\n', 3) == nullptr);
22 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '\n', 3) == nullptr);
25 void TestShortString() {
26 const char* test = "0123456789\n";
28 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '0', 10) == test + 0x0);
29 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '0', 10) == test + 0x0);
30 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '1', 10) == test + 0x1);
31 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '1', 10) == test + 0x1);
32 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '2', 10) == test + 0x2);
33 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '2', 10) == test + 0x2);
34 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '3', 10) == test + 0x3);
35 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '3', 10) == test + 0x3);
36 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '4', 10) == test + 0x4);
37 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '4', 10) == test + 0x4);
38 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '5', 10) == test + 0x5);
39 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '5', 10) == test + 0x5);
40 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '6', 10) == test + 0x6);
41 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '6', 10) == test + 0x6);
42 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '7', 10) == test + 0x7);
43 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '7', 10) == test + 0x7);
44 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '8', 10) == test + 0x8);
45 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '8', 10) == test + 0x8);
46 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '9', 10) == test + 0x9);
47 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '9', 10) == test + 0x9);
48 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '\n', 10) == nullptr);
49 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '\n', 10) == nullptr);
52 void TestMediumString() {
53 const char* test = "0123456789abcdef\n";
55 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '0', 16) == test + 0x0);
56 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '0', 16) == test + 0x0);
57 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '1', 16) == test + 0x1);
58 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '1', 16) == test + 0x1);
59 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '2', 16) == test + 0x2);
60 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '2', 16) == test + 0x2);
61 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '3', 16) == test + 0x3);
62 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '3', 16) == test + 0x3);
63 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '4', 16) == test + 0x4);
64 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '4', 16) == test + 0x4);
65 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '5', 16) == test + 0x5);
66 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '5', 16) == test + 0x5);
67 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '6', 16) == test + 0x6);
68 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '6', 16) == test + 0x6);
69 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '7', 16) == test + 0x7);
70 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '7', 16) == test + 0x7);
71 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '8', 16) == test + 0x8);
72 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '8', 16) == test + 0x8);
73 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '9', 16) == test + 0x9);
74 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '9', 16) == test + 0x9);
75 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, 'a', 16) == test + 0xa);
76 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, 'a', 16) == test + 0xa);
77 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, 'b', 16) == test + 0xb);
78 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, 'b', 16) == test + 0xb);
79 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, 'c', 16) == test + 0xc);
80 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, 'c', 16) == test + 0xc);
81 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, 'd', 16) == test + 0xd);
82 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, 'd', 16) == test + 0xd);
83 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, 'e', 16) == test + 0xe);
84 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, 'e', 16) == test + 0xe);
85 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, 'f', 16) == test + 0xf);
86 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, 'f', 16) == test + 0xf);
87 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, '\n', 16) == nullptr);
88 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test, '\n', 16) == nullptr);
91 void TestLongString() {
92 // NOTE: here we make sure we go all the way up to 256 to ensure we're
93 // handling negative-valued chars appropriately. We don't need to bother
94 // testing this side of things with char16_t's because they are very
95 // sensibly guaranteed to be unsigned.
96 const size_t count = 256;
97 char test[count];
98 for (size_t i = 0; i < count; ++i) {
99 test[i] = static_cast<char>(i);
102 for (size_t i = 0; i < count - 1; ++i) {
103 MOZ_RELEASE_ASSERT(SIMD::memchr8(test, static_cast<char>(i), count - 1) ==
104 test + i);
105 MOZ_RELEASE_ASSERT(
106 SIMD::memchr8SSE2(test, static_cast<char>(i), count - 1) == test + i);
108 MOZ_RELEASE_ASSERT(
109 SIMD::memchr8(test, static_cast<char>(count - 1), count - 1) == nullptr);
112 void TestGauntlet() {
113 const size_t count = 256;
114 char test[count];
115 for (size_t i = 0; i < count; ++i) {
116 test[i] = static_cast<char>(i);
119 for (size_t i = 0; i < count - 1; ++i) {
120 for (size_t j = 0; j < count - 1; ++j) {
121 for (size_t k = 0; k < count - 1; ++k) {
122 if (i >= k) {
123 const char* expected = nullptr;
124 if (j >= k && j < i) {
125 expected = test + j;
127 MOZ_RELEASE_ASSERT(
128 SIMD::memchr8(test + k, static_cast<char>(j), i - k) == expected);
129 MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test + k, static_cast<char>(j),
130 i - k) == expected);
137 void TestTinyString16() {
138 const char16_t* test = u"012\n";
140 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'0', 3) == test + 0x0);
141 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'0', 3) == test + 0x0);
142 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'1', 3) == test + 0x1);
143 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'1', 3) == test + 0x1);
144 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'2', 3) == test + 0x2);
145 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'2', 3) == test + 0x2);
146 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'\n', 3) == nullptr);
147 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'\n', 3) == nullptr);
150 void TestShortString16() {
151 const char16_t* test = u"0123456789\n";
153 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'0', 10) == test + 0x0);
154 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'0', 10) == test + 0x0);
155 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'1', 10) == test + 0x1);
156 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'1', 10) == test + 0x1);
157 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'2', 10) == test + 0x2);
158 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'2', 10) == test + 0x2);
159 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'3', 10) == test + 0x3);
160 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'3', 10) == test + 0x3);
161 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'4', 10) == test + 0x4);
162 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'4', 10) == test + 0x4);
163 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'5', 10) == test + 0x5);
164 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'5', 10) == test + 0x5);
165 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'6', 10) == test + 0x6);
166 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'6', 10) == test + 0x6);
167 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'7', 10) == test + 0x7);
168 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'7', 10) == test + 0x7);
169 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'8', 10) == test + 0x8);
170 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'8', 10) == test + 0x8);
171 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'9', 10) == test + 0x9);
172 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'9', 10) == test + 0x9);
173 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'\n', 10) == nullptr);
174 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'\n', 10) == nullptr);
177 void TestMediumString16() {
178 const char16_t* test = u"0123456789abcdef\n";
180 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'0', 16) == test + 0x0);
181 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'0', 16) == test + 0x0);
182 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'1', 16) == test + 0x1);
183 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'1', 16) == test + 0x1);
184 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'2', 16) == test + 0x2);
185 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'2', 16) == test + 0x2);
186 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'3', 16) == test + 0x3);
187 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'3', 16) == test + 0x3);
188 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'4', 16) == test + 0x4);
189 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'4', 16) == test + 0x4);
190 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'5', 16) == test + 0x5);
191 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'5', 16) == test + 0x5);
192 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'6', 16) == test + 0x6);
193 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'6', 16) == test + 0x6);
194 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'7', 16) == test + 0x7);
195 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'7', 16) == test + 0x7);
196 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'8', 16) == test + 0x8);
197 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'8', 16) == test + 0x8);
198 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'9', 16) == test + 0x9);
199 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'9', 16) == test + 0x9);
200 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'a', 16) == test + 0xa);
201 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'a', 16) == test + 0xa);
202 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'b', 16) == test + 0xb);
203 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'b', 16) == test + 0xb);
204 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'c', 16) == test + 0xc);
205 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'c', 16) == test + 0xc);
206 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'd', 16) == test + 0xd);
207 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'd', 16) == test + 0xd);
208 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'e', 16) == test + 0xe);
209 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'e', 16) == test + 0xe);
210 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'f', 16) == test + 0xf);
211 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'f', 16) == test + 0xf);
212 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u'\n', 16) == nullptr);
213 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u'\n', 16) == nullptr);
216 void TestLongString16() {
217 const size_t count = 256;
218 char16_t test[count];
219 for (size_t i = 0; i < count; ++i) {
220 test[i] = i;
223 for (size_t i = 0; i < count - 1; ++i) {
224 MOZ_RELEASE_ASSERT(
225 SIMD::memchr16(test, static_cast<char16_t>(i), count - 1) == test + i);
226 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, static_cast<char16_t>(i),
227 count - 1) == test + i);
229 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, count - 1, count - 1) == nullptr);
230 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, count - 1, count - 1) == nullptr);
233 void TestGauntlet16() {
234 const size_t count = 257;
235 char16_t test[count];
236 for (size_t i = 0; i < count; ++i) {
237 test[i] = i;
240 for (size_t i = 0; i < count - 1; ++i) {
241 for (size_t j = 0; j < count - 1; ++j) {
242 for (size_t k = 0; k < count - 1; ++k) {
243 if (i >= k) {
244 const char16_t* expected = nullptr;
245 if (j >= k && j < i) {
246 expected = test + j;
248 MOZ_RELEASE_ASSERT(SIMD::memchr16(test + k, static_cast<char16_t>(j),
249 i - k) == expected);
250 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test + k,
251 static_cast<char16_t>(j),
252 i - k) == expected);
259 void TestTinyString64() {
260 const uint64_t test[4] = {0, 1, 2, 3};
262 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 0, 3) == test + 0x0);
263 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 1, 3) == test + 0x1);
264 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 2, 3) == test + 0x2);
265 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 3, 3) == nullptr);
268 void TestShortString64() {
269 const uint64_t test[16] = {0, 1, 2, 3, 4, 5, 6, 7,
270 8, 9, 10, 11, 12, 13, 14, 15};
272 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 0, 15) == test + 0);
273 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 1, 15) == test + 1);
274 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 2, 15) == test + 2);
275 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 3, 15) == test + 3);
276 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 4, 15) == test + 4);
277 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 5, 15) == test + 5);
278 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 6, 15) == test + 6);
279 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 7, 15) == test + 7);
280 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 8, 15) == test + 8);
281 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 9, 15) == test + 9);
282 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 9, 15) == test + 9);
283 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 10, 15) == test + 10);
284 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 11, 15) == test + 11);
285 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 12, 15) == test + 12);
286 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 13, 15) == test + 13);
287 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 14, 15) == test + 14);
288 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 15, 15) == nullptr);
291 void TestMediumString64() {
292 const uint64_t test[32] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
293 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
294 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
296 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 0, 31) == test + 0);
297 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 1, 31) == test + 1);
298 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 2, 31) == test + 2);
299 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 3, 31) == test + 3);
300 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 4, 31) == test + 4);
301 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 5, 31) == test + 5);
302 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 6, 31) == test + 6);
303 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 7, 31) == test + 7);
304 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 8, 31) == test + 8);
305 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 9, 31) == test + 9);
306 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 9, 31) == test + 9);
307 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 10, 31) == test + 10);
308 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 11, 31) == test + 11);
309 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 12, 31) == test + 12);
310 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 13, 31) == test + 13);
311 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 14, 31) == test + 14);
312 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 15, 31) == test + 15);
313 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 16, 31) == test + 16);
314 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 17, 31) == test + 17);
315 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 18, 31) == test + 18);
316 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 19, 31) == test + 19);
317 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 20, 31) == test + 20);
318 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 21, 31) == test + 21);
319 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 22, 31) == test + 22);
320 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 23, 31) == test + 23);
321 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 24, 31) == test + 24);
322 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 25, 31) == test + 25);
323 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 26, 31) == test + 26);
324 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 27, 31) == test + 27);
325 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 28, 31) == test + 28);
326 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 29, 31) == test + 29);
327 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 30, 31) == test + 30);
328 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, 31, 31) == nullptr);
331 void TestLongString64() {
332 const size_t count = 256;
333 uint64_t test[count];
334 for (size_t i = 0; i < count; ++i) {
335 test[i] = i;
338 for (uint64_t i = 0; i < count - 1; ++i) {
339 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, i, count - 1) == test + i);
341 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, count - 1, count - 1) == nullptr);
344 void TestGauntlet64() {
345 const size_t count = 257;
346 uint64_t test[count];
347 for (size_t i = 0; i < count; ++i) {
348 test[i] = i;
351 for (uint64_t i = 0; i < count - 1; ++i) {
352 for (uint64_t j = 0; j < count - 1; ++j) {
353 for (uint64_t k = 0; k < count - 1; ++k) {
354 if (i >= k) {
355 const uint64_t* expected = nullptr;
356 if (j >= k && j < i) {
357 expected = test + j;
359 MOZ_RELEASE_ASSERT(SIMD::memchr64(test + k, j, i - k) == expected);
366 void TestTinyString2x8() {
367 const char* test = "012\n";
369 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '0', '1', 3) == test + 0x0);
370 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '1', '2', 3) == test + 0x1);
371 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '2', '\n', 3) == nullptr);
372 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '0', '2', 3) == nullptr);
373 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '1', '\n', 3) == nullptr);
376 void TestShortString2x8() {
377 const char* test = "0123456789\n";
379 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '0', '1', 10) == test + 0x0);
380 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '1', '2', 10) == test + 0x1);
381 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '2', '3', 10) == test + 0x2);
382 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '3', '4', 10) == test + 0x3);
383 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '4', '5', 10) == test + 0x4);
384 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '5', '6', 10) == test + 0x5);
385 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '6', '7', 10) == test + 0x6);
386 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '7', '8', 10) == test + 0x7);
387 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '8', '9', 10) == test + 0x8);
388 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '9', '\n', 10) == nullptr);
391 void TestMediumString2x8() {
392 const char* test = "0123456789abcdef\n";
394 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '0', '1', 16) == test + 0x0);
395 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '1', '2', 16) == test + 0x1);
396 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '2', '3', 16) == test + 0x2);
397 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '3', '4', 16) == test + 0x3);
398 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '4', '5', 16) == test + 0x4);
399 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '5', '6', 16) == test + 0x5);
400 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '6', '7', 16) == test + 0x6);
401 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '7', '8', 16) == test + 0x7);
402 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '8', '9', 16) == test + 0x8);
403 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, '9', 'a', 16) == test + 0x9);
404 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, 'a', 'b', 16) == test + 0xa);
405 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, 'b', 'c', 16) == test + 0xb);
406 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, 'c', 'd', 16) == test + 0xc);
407 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, 'd', 'e', 16) == test + 0xd);
408 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, 'e', 'f', 16) == test + 0xe);
409 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, 'f', '\n', 16) == nullptr);
412 void TestLongString2x8() {
413 const size_t count = 256;
414 char test[count];
415 for (size_t i = 0; i < count; ++i) {
416 test[i] = static_cast<char>(i);
419 for (size_t i = 0; i < count - 2; ++i) {
420 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, static_cast<char>(i),
421 static_cast<char>(i + 1),
422 count - 1) == test + i);
424 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, static_cast<char>(count - 2),
425 static_cast<char>(count - 1),
426 count - 1) == nullptr);
429 void TestTinyString2x16() {
430 const char16_t* test = u"012\n";
432 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'0', u'1', 3) == test + 0x0);
433 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'1', u'2', 3) == test + 0x1);
434 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'2', u'\n', 3) == nullptr);
435 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'0', u'2', 3) == nullptr);
436 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'1', u'\n', 3) == nullptr);
439 void TestShortString2x16() {
440 const char16_t* test = u"0123456789\n";
442 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'0', u'1', 10) == test + 0x0);
443 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'1', u'2', 10) == test + 0x1);
444 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'2', u'3', 10) == test + 0x2);
445 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'3', u'4', 10) == test + 0x3);
446 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'4', u'5', 10) == test + 0x4);
447 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'5', u'6', 10) == test + 0x5);
448 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'6', u'7', 10) == test + 0x6);
449 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'7', u'8', 10) == test + 0x7);
450 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'8', u'9', 10) == test + 0x8);
451 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'9', u'\n', 10) == nullptr);
452 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'0', u'2', 10) == nullptr);
455 void TestMediumString2x16() {
456 const char16_t* test = u"0123456789abcdef\n";
458 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'0', u'1', 16) == test + 0x0);
459 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'1', u'2', 16) == test + 0x1);
460 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'2', u'3', 16) == test + 0x2);
461 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'3', u'4', 16) == test + 0x3);
462 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'4', u'5', 16) == test + 0x4);
463 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'5', u'6', 16) == test + 0x5);
464 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'6', u'7', 16) == test + 0x6);
465 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'7', u'8', 16) == test + 0x7);
466 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'8', u'9', 16) == test + 0x8);
467 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'9', u'a', 16) == test + 0x9);
468 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'a', u'b', 16) == test + 0xa);
469 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'b', u'c', 16) == test + 0xb);
470 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'c', u'd', 16) == test + 0xc);
471 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'd', u'e', 16) == test + 0xd);
472 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'e', u'f', 16) == test + 0xe);
473 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'f', u'\n', 16) == nullptr);
474 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u'0', u'2', 10) == nullptr);
477 void TestLongString2x16() {
478 const size_t count = 257;
479 char16_t test[count];
480 for (size_t i = 0; i < count; ++i) {
481 test[i] = static_cast<char16_t>(i);
484 for (size_t i = 0; i < count - 2; ++i) {
485 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, static_cast<char16_t>(i),
486 static_cast<char16_t>(i + 1),
487 count - 1) == test + i);
489 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, static_cast<char16_t>(count - 2),
490 static_cast<char16_t>(count - 1),
491 count - 1) == nullptr);
494 void TestGauntlet2x8() {
495 const size_t count = 256;
496 char test[count * 2];
497 // load in the evens
498 for (size_t i = 0; i < count / 2; ++i) {
499 test[i] = static_cast<char>(2 * i);
501 // load in the odds
502 for (size_t i = 0; i < count / 2; ++i) {
503 test[count / 2 + i] = static_cast<char>(2 * i + 1);
505 // load in evens and odds sequentially
506 for (size_t i = 0; i < count; ++i) {
507 test[count + i] = static_cast<char>(i);
510 for (size_t i = 0; i < count - 1; ++i) {
511 for (size_t j = 0; j < count - 2; ++j) {
512 for (size_t k = 0; k < count - 1; ++k) {
513 if (i > k + 1) {
514 const char* expected1 = nullptr;
515 const char* expected2 = nullptr;
516 if (i > j + 1) {
517 expected1 = test + j + count; // Add count to skip over odds/evens
518 if (j >= k) {
519 expected2 = test + j + count;
522 char a = static_cast<char>(j);
523 char b = static_cast<char>(j + 1);
524 // Make sure it doesn't pick up any in the alternating odd/even
525 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test + k, a, b, i - k + count) ==
526 expected1);
527 // Make sure we cover smaller inputs
528 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test + k + count, a, b, i - k) ==
529 expected2);
536 void TestGauntlet2x16() {
537 const size_t count = 1024;
538 char16_t test[count * 2];
539 // load in the evens
540 for (size_t i = 0; i < count / 2; ++i) {
541 test[i] = static_cast<char16_t>(2 * i);
543 // load in the odds
544 for (size_t i = 0; i < count / 2; ++i) {
545 test[count / 2 + i] = static_cast<char16_t>(2 * i + 1);
547 // load in evens and odds sequentially
548 for (size_t i = 0; i < count; ++i) {
549 test[count + i] = static_cast<char16_t>(i);
552 for (size_t i = 0; i < count - 1; ++i) {
553 for (size_t j = 0; j < count - 2; ++j) {
554 for (size_t k = 0; k < count - 1; ++k) {
555 if (i > k + 1) {
556 const char16_t* expected1 = nullptr;
557 const char16_t* expected2 = nullptr;
558 if (i > j + 1) {
559 expected1 = test + j + count; // Add count to skip over odds/evens
560 if (j >= k) {
561 expected2 = test + j + count;
564 char16_t a = static_cast<char16_t>(j);
565 char16_t b = static_cast<char16_t>(j + 1);
566 // Make sure it doesn't pick up any in the alternating odd/even
567 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test + k, a, b, i - k + count) ==
568 expected1);
569 // Make sure we cover smaller inputs
570 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test + k + count, a, b, i - k) ==
571 expected2);
578 void TestSpecialCases() {
579 // The following 4 asserts test the case where we do two overlapping checks,
580 // where the first one ends with our first search character, and the second
581 // one begins with our search character. Since they are overlapping, we want
582 // to ensure that the search function doesn't carry the match from the
583 // first check over to the second check.
584 const char* test1 = "x123456789abcdey";
585 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test1, 'y', 'x', 16) == nullptr);
586 const char* test2 = "1000000000000000200000000000000030b000000000000a40";
587 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test2, 'a', 'b', 50) == nullptr);
588 const char16_t* test1wide = u"x123456y";
589 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test1wide, 'y', 'x', 8) == nullptr);
590 const char16_t* test2wide = u"100000002000000030b0000a40";
591 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test2wide, 'a', 'b', 26) == nullptr);
594 int main(void) {
595 TestTinyString();
596 TestShortString();
597 TestMediumString();
598 TestLongString();
599 TestGauntlet();
601 TestTinyString16();
602 TestShortString16();
603 TestMediumString16();
604 TestLongString16();
605 TestGauntlet16();
607 TestTinyString64();
608 TestShortString64();
609 TestMediumString64();
610 TestLongString64();
611 TestGauntlet64();
613 TestTinyString2x8();
614 TestShortString2x8();
615 TestMediumString2x8();
616 TestLongString2x8();
618 TestTinyString2x16();
619 TestShortString2x16();
620 TestMediumString2x16();
621 TestLongString2x16();
623 TestSpecialCases();
625 // These are too slow to run all the time, but they should be run when making
626 // meaningful changes just to be sure.
627 // TestGauntlet2x8();
628 // TestGauntlet2x16();
630 return 0;