/* -*- Mode: C++; tab-width: 9; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Assertions.h"
#include "mozilla/SIMD.h"
using mozilla::SIMD;
void TestTinyString() {
const char* test =
"012\n";
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'0',
3) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'0',
3) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'1',
3) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'1',
3) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'2',
3) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'2',
3) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'\n',
3) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'\n',
3) == nullptr);
}
void TestShortString() {
const char* test =
"0123456789\n";
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'0',
10) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'0',
10) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'1',
10) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'1',
10) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'2',
10) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'2',
10) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'3',
10) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'3',
10) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'4',
10) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'4',
10) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'5',
10) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'5',
10) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'6',
10) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'6',
10) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'7',
10) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'7',
10) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'8',
10) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'8',
10) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'9',
10) == test +
0x9);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'9',
10) == test +
0x9);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'\n',
10) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'\n',
10) == nullptr);
}
void TestMediumString() {
const char* test =
"0123456789abcdef\n";
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'0',
16) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'0',
16) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'1',
16) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'1',
16) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'2',
16) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'2',
16) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'3',
16) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'3',
16) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'4',
16) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'4',
16) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'5',
16) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'5',
16) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'6',
16) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'6',
16) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'7',
16) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'7',
16) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'8',
16) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'8',
16) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'9',
16) == test +
0x9);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'9',
16) == test +
0x9);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'a',
16) == test +
0xa);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'a',
16) == test +
0xa);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'b',
16) == test +
0xb);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'b',
16) == test +
0xb);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'c',
16) == test +
0xc);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'c',
16) == test +
0xc);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'd',
16) == test +
0xd);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'd',
16) == test +
0xd);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'e',
16) == test +
0xe);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'e',
16) == test +
0xe);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'f',
16) == test +
0xf);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'f',
16) == test +
0xf);
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
'\n',
16) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test,
'\n',
16) == nullptr);
}
void TestLongString() {
// NOTE: here we make sure we go all the way up to 256 to ensure we're
// handling negative-valued chars appropriately. We don't need to bother
// testing this side of things with char16_t's because they are very
// sensibly guaranteed to be unsigned.
const size_t count =
256;
char test[count];
for (size_t i =
0; i < count; ++i) {
test[i] =
static_cast<
char>(i);
}
for (size_t i =
0; i < count -
1; ++i) {
MOZ_RELEASE_ASSERT(SIMD::memchr8(test,
static_cast<
char>(i), count -
1) ==
test + i);
MOZ_RELEASE_ASSERT(
SIMD::memchr8SSE2(test,
static_cast<
char>(i), count -
1) == test + i);
}
MOZ_RELEASE_ASSERT(
SIMD::memchr8(test,
static_cast<
char>(count -
1), count -
1) == nullptr);
}
void TestGauntlet() {
const size_t count =
256;
char test[count];
for (size_t i =
0; i < count; ++i) {
test[i] =
static_cast<
char>(i);
}
for (size_t i =
0; i < count -
1; ++i) {
for (size_t j =
0; j < count -
1; ++j) {
for (size_t k =
0; k < count -
1; ++k) {
if (i >= k) {
const char* expected = nullptr;
if (j >= k && j < i) {
expected = test + j;
}
MOZ_RELEASE_ASSERT(
SIMD::memchr8(test + k,
static_cast<
char>(j), i - k) == expected);
MOZ_RELEASE_ASSERT(SIMD::memchr8SSE2(test + k,
static_cast<
char>(j),
i - k) == expected);
}
}
}
}
}
void TestTinyString16() {
const char16_t* test = u
"012\n";
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'0',
3) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'0',
3) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'1',
3) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'1',
3) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'2',
3) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'2',
3) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'\n',
3) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'\n',
3) == nullptr);
}
void TestShortString16() {
const char16_t* test = u
"0123456789\n";
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'0',
10) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'0',
10) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'1',
10) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'1',
10) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'2',
10) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'2',
10) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'3',
10) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'3',
10) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'4',
10) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'4',
10) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'5',
10) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'5',
10) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'6',
10) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'6',
10) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'7',
10) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'7',
10) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'8',
10) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'8',
10) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'9',
10) == test +
0x9);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'9',
10) == test +
0x9);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'\n',
10) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'\n',
10) == nullptr);
}
void TestMediumString16() {
const char16_t* test = u
"0123456789abcdef\n";
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'0',
16) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'0',
16) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'1',
16) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'1',
16) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'2',
16) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'2',
16) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'3',
16) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'3',
16) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'4',
16) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'4',
16) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'5',
16) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'5',
16) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'6',
16) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'6',
16) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'7',
16) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'7',
16) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'8',
16) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'8',
16) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'9',
16) == test +
0x9);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'9',
16) == test +
0x9);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'a',
16) == test +
0xa);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'a',
16) == test +
0xa);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'b',
16) == test +
0xb);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'b',
16) == test +
0xb);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'c',
16) == test +
0xc);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'c',
16) == test +
0xc);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'd',
16) == test +
0xd);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'd',
16) == test +
0xd);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'e',
16) == test +
0xe);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'e',
16) == test +
0xe);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'f',
16) == test +
0xf);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'f',
16) == test +
0xf);
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, u
'\n',
16) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, u
'\n',
16) == nullptr);
}
void TestLongString16() {
const size_t count =
256;
char16_t test[count];
for (size_t i =
0; i < count; ++i) {
test[i] = i;
}
for (size_t i =
0; i < count -
1; ++i) {
MOZ_RELEASE_ASSERT(
SIMD::memchr16(test,
static_cast<char16_t>(i), count -
1) == test + i);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test,
static_cast<char16_t>(i),
count -
1) == test + i);
}
MOZ_RELEASE_ASSERT(SIMD::memchr16(test, count -
1, count -
1) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, count -
1, count -
1) == nullptr);
}
void TestGauntlet16() {
const size_t count =
257;
char16_t test[count];
for (size_t i =
0; i < count; ++i) {
test[i] = i;
}
for (size_t i =
0; i < count -
1; ++i) {
for (size_t j =
0; j < count -
1; ++j) {
for (size_t k =
0; k < count -
1; ++k) {
if (i >= k) {
const char16_t* expected = nullptr;
if (j >= k && j < i) {
expected = test + j;
}
MOZ_RELEASE_ASSERT(SIMD::memchr16(test + k,
static_cast<char16_t>(j),
i - k) == expected);
MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test + k,
static_cast<char16_t>(j),
i - k) == expected);
}
}
}
}
}
void TestTinyString64() {
const uint64_t test[
4] = {
0,
1,
2,
3};
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
0,
3) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
1,
3) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
2,
3) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
3,
3) == nullptr);
}
void TestShortString64() {
const uint64_t test[
16] = {
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15};
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
0,
15) == test +
0);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
1,
15) == test +
1);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
2,
15) == test +
2);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
3,
15) == test +
3);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
4,
15) == test +
4);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
5,
15) == test +
5);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
6,
15) == test +
6);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
7,
15) == test +
7);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
8,
15) == test +
8);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
9,
15) == test +
9);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
9,
15) == test +
9);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
10,
15) == test +
10);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
11,
15) == test +
11);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
12,
15) == test +
12);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
13,
15) == test +
13);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
14,
15) == test +
14);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
15,
15) == nullptr);
}
void TestMediumString64() {
const uint64_t test[
32] = {
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31};
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
0,
31) == test +
0);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
1,
31) == test +
1);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
2,
31) == test +
2);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
3,
31) == test +
3);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
4,
31) == test +
4);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
5,
31) == test +
5);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
6,
31) == test +
6);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
7,
31) == test +
7);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
8,
31) == test +
8);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
9,
31) == test +
9);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
9,
31) == test +
9);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
10,
31) == test +
10);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
11,
31) == test +
11);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
12,
31) == test +
12);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
13,
31) == test +
13);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
14,
31) == test +
14);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
15,
31) == test +
15);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
16,
31) == test +
16);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
17,
31) == test +
17);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
18,
31) == test +
18);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
19,
31) == test +
19);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
20,
31) == test +
20);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
21,
31) == test +
21);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
22,
31) == test +
22);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
23,
31) == test +
23);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
24,
31) == test +
24);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
25,
31) == test +
25);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
26,
31) == test +
26);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
27,
31) == test +
27);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
28,
31) == test +
28);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
29,
31) == test +
29);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
30,
31) == test +
30);
MOZ_RELEASE_ASSERT(SIMD::memchr64(test,
31,
31) == nullptr);
}
void TestLongString64() {
const size_t count =
256;
uint64_t test[count];
for (size_t i =
0; i < count; ++i) {
test[i] = i;
}
for (uint64_t i =
0; i < count -
1; ++i) {
MOZ_RELEASE_ASSERT(SIMD::memchr64(test, i, count -
1) == test + i);
}
MOZ_RELEASE_ASSERT(SIMD::memchr64(test, count -
1, count -
1) == nullptr);
}
void TestGauntlet64() {
const size_t count =
257;
uint64_t test[count];
for (size_t i =
0; i < count; ++i) {
test[i] = i;
}
for (uint64_t i =
0; i < count -
1; ++i) {
for (uint64_t j =
0; j < count -
1; ++j) {
for (uint64_t k =
0; k < count -
1; ++k) {
if (i >= k) {
const uint64_t* expected = nullptr;
if (j >= k && j < i) {
expected = test + j;
}
MOZ_RELEASE_ASSERT(SIMD::memchr64(test + k, j, i - k) == expected);
}
}
}
}
}
void TestTinyString2x8() {
const char* test =
"012\n";
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'0',
'1',
3) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'1',
'2',
3) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'2',
'\n',
3) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'0',
'2',
3) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'1',
'\n',
3) == nullptr);
}
void TestShortString2x8() {
const char* test =
"0123456789\n";
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'0',
'1',
10) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'1',
'2',
10) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'2',
'3',
10) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'3',
'4',
10) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'4',
'5',
10) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'5',
'6',
10) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'6',
'7',
10) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'7',
'8',
10) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'8',
'9',
10) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'9',
'\n',
10) == nullptr);
}
void TestMediumString2x8() {
const char* test =
"0123456789abcdef\n";
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'0',
'1',
16) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'1',
'2',
16) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'2',
'3',
16) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'3',
'4',
16) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'4',
'5',
16) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'5',
'6',
16) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'6',
'7',
16) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'7',
'8',
16) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'8',
'9',
16) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'9',
'a',
16) == test +
0x9);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'a',
'b',
16) == test +
0xa);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'b',
'c',
16) == test +
0xb);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'c',
'd',
16) == test +
0xc);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'd',
'e',
16) == test +
0xd);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'e',
'f',
16) == test +
0xe);
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
'f',
'\n',
16) == nullptr);
}
void TestLongString2x8() {
const size_t count =
256;
char test[count];
for (size_t i =
0; i < count; ++i) {
test[i] =
static_cast<
char>(i);
}
for (size_t i =
0; i < count -
2; ++i) {
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
static_cast<
char>(i),
static_cast<
char>(i +
1),
count -
1) == test + i);
}
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test,
static_cast<
char>(count -
2),
static_cast<
char>(count -
1),
count -
1) == nullptr);
}
void TestTinyString2x16() {
const char16_t* test = u
"012\n";
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'0', u
'1',
3) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'1', u
'2',
3) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'2', u
'\n',
3) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'0', u
'2',
3) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'1', u
'\n',
3) == nullptr);
}
void TestShortString2x16() {
const char16_t* test = u
"0123456789\n";
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'0', u
'1',
10) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'1', u
'2',
10) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'2', u
'3',
10) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'3', u
'4',
10) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'4', u
'5',
10) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'5', u
'6',
10) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'6', u
'7',
10) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'7', u
'8',
10) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'8', u
'9',
10) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'9', u
'\n',
10) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'0', u
'2',
10) == nullptr);
}
void TestMediumString2x16() {
const char16_t* test = u
"0123456789abcdef\n";
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'0', u
'1',
16) == test +
0x0);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'1', u
'2',
16) == test +
0x1);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'2', u
'3',
16) == test +
0x2);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'3', u
'4',
16) == test +
0x3);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'4', u
'5',
16) == test +
0x4);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'5', u
'6',
16) == test +
0x5);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'6', u
'7',
16) == test +
0x6);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'7', u
'8',
16) == test +
0x7);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'8', u
'9',
16) == test +
0x8);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'9', u
'a',
16) == test +
0x9);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'a', u
'b',
16) == test +
0xa);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'b', u
'c',
16) == test +
0xb);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'c', u
'd',
16) == test +
0xc);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'd', u
'e',
16) == test +
0xd);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'e', u
'f',
16) == test +
0xe);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'f', u
'\n',
16) == nullptr);
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, u
'0', u
'2',
10) == nullptr);
}
void TestLongString2x16() {
const size_t count =
257;
char16_t test[count];
for (size_t i =
0; i < count; ++i) {
test[i] =
static_cast<char16_t>(i);
}
for (size_t i =
0; i < count -
2; ++i) {
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test,
static_cast<char16_t>(i),
static_cast<char16_t>(i +
1),
count -
1) == test + i);
}
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test,
static_cast<char16_t>(count -
2),
static_cast<char16_t>(count -
1),
count -
1) == nullptr);
}
void TestGauntlet2x8() {
const size_t count =
256;
char test[count *
2];
// load in the evens
for (size_t i =
0; i < count /
2; ++i) {
test[i] =
static_cast<
char>(
2 * i);
}
// load in the odds
for (size_t i =
0; i < count /
2; ++i) {
test[count /
2 + i] =
static_cast<
char>(
2 * i +
1);
}
// load in evens and odds sequentially
for (size_t i =
0; i < count; ++i) {
test[count + i] =
static_cast<
char>(i);
}
for (size_t i =
0; i < count -
1; ++i) {
for (size_t j =
0; j < count -
2; ++j) {
for (size_t k =
0; k < count -
1; ++k) {
if (i > k +
1) {
const char* expected1 = nullptr;
const char* expected2 = nullptr;
if (i > j +
1) {
expected1 = test + j + count;
// Add count to skip over odds/evens
if (j >= k) {
expected2 = test + j + count;
}
}
char a =
static_cast<
char>(j);
char b =
static_cast<
char>(j +
1);
// Make sure it doesn't pick up any in the alternating odd/even
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test + k, a, b, i - k + count) ==
expected1);
// Make sure we cover smaller inputs
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test + k + count, a, b, i - k) ==
expected2);
}
}
}
}
}
void TestGauntlet2x16() {
const size_t count =
1024;
char16_t test[count *
2];
// load in the evens
for (size_t i =
0; i < count /
2; ++i) {
test[i] =
static_cast<char16_t>(
2 * i);
}
// load in the odds
for (size_t i =
0; i < count /
2; ++i) {
test[count /
2 + i] =
static_cast<char16_t>(
2 * i +
1);
}
// load in evens and odds sequentially
for (size_t i =
0; i < count; ++i) {
test[count + i] =
static_cast<char16_t>(i);
}
for (size_t i =
0; i < count -
1; ++i) {
for (size_t j =
0; j < count -
2; ++j) {
for (size_t k =
0; k < count -
1; ++k) {
if (i > k +
1) {
const char16_t* expected1 = nullptr;
const char16_t* expected2 = nullptr;
if (i > j +
1) {
expected1 = test + j + count;
// Add count to skip over odds/evens
if (j >= k) {
expected2 = test + j + count;
}
}
char16_t a =
static_cast<char16_t>(j);
char16_t b =
static_cast<char16_t>(j +
1);
// Make sure it doesn't pick up any in the alternating odd/even
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test + k, a, b, i - k + count) ==
expected1);
// Make sure we cover smaller inputs
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test + k + count, a, b, i - k) ==
expected2);
}
}
}
}
}
void TestSpecialCases() {
// The following 4 asserts test the case where we do two overlapping checks,
// where the first one ends with our first search character, and the second
// one begins with our search character. Since they are overlapping, we want
// to ensure that the search function doesn't carry the match from the
// first check over to the second check.
const char* test1 =
"x123456789abcdey";
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test1,
'y',
'x',
16) == nullptr);
const char* test2 =
"1000000000000000200000000000000030b000000000000a40";
MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test2,
'a',
'b',
50) == nullptr);
const char16_t* test1wide = u
"x123456y";
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test1wide,
'y',
'x',
8) == nullptr);
const char16_t* test2wide = u
"100000002000000030b0000a40";
MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test2wide,
'a',
'b',
26) == nullptr);
}
int main(
void) {
TestTinyString();
TestShortString();
TestMediumString();
TestLongString();
TestGauntlet();
TestTinyString16();
TestShortString16();
TestMediumString16();
TestLongString16();
TestGauntlet16();
TestTinyString64();
TestShortString64();
TestMediumString64();
TestLongString64();
TestGauntlet64();
TestTinyString2x8();
TestShortString2x8();
TestMediumString2x8();
TestLongString2x8();
TestTinyString2x16();
TestShortString2x16();
TestMediumString2x16();
TestLongString2x16();
TestSpecialCases();
// These are too slow to run all the time, but they should be run when making
// meaningful changes just to be sure.
// TestGauntlet2x8();
// TestGauntlet2x16();
return 0;
}