TestSIMD.cpp (28115B)
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/. */ 6 7 #include "mozilla/Assertions.h" 8 #include "mozilla/SIMD.h" 9 10 using mozilla::SIMD; 11 12 void TestTinyString() { 13 const char* test = "012\n"; 14 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); 23 } 24 25 void TestShortString() { 26 const char* test = "0123456789\n"; 27 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); 50 } 51 52 void TestMediumString() { 53 const char* test = "0123456789abcdef\n"; 54 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); 89 } 90 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); 100 } 101 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); 107 } 108 MOZ_RELEASE_ASSERT( 109 SIMD::memchr8(test, static_cast<char>(count - 1), count - 1) == nullptr); 110 } 111 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); 117 } 118 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; 126 } 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); 131 } 132 } 133 } 134 } 135 } 136 137 void TestTinyString16() { 138 const char16_t* test = u"012\n"; 139 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); 148 } 149 150 void TestShortString16() { 151 const char16_t* test = u"0123456789\n"; 152 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); 175 } 176 177 void TestMediumString16() { 178 const char16_t* test = u"0123456789abcdef\n"; 179 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); 214 } 215 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; 221 } 222 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); 228 } 229 MOZ_RELEASE_ASSERT(SIMD::memchr16(test, count - 1, count - 1) == nullptr); 230 MOZ_RELEASE_ASSERT(SIMD::memchr16SSE2(test, count - 1, count - 1) == nullptr); 231 } 232 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; 238 } 239 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; 247 } 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); 253 } 254 } 255 } 256 } 257 } 258 259 void TestTinyString64() { 260 const uint64_t test[4] = {0, 1, 2, 3}; 261 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); 266 } 267 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}; 271 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); 289 } 290 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}; 295 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); 329 } 330 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; 336 } 337 338 for (uint64_t i = 0; i < count - 1; ++i) { 339 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, i, count - 1) == test + i); 340 } 341 MOZ_RELEASE_ASSERT(SIMD::memchr64(test, count - 1, count - 1) == nullptr); 342 } 343 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; 349 } 350 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; 358 } 359 MOZ_RELEASE_ASSERT(SIMD::memchr64(test + k, j, i - k) == expected); 360 } 361 } 362 } 363 } 364 } 365 366 void TestTinyString2x8() { 367 const char* test = "012\n"; 368 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); 374 } 375 376 void TestShortString2x8() { 377 const char* test = "0123456789\n"; 378 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); 389 } 390 391 void TestMediumString2x8() { 392 const char* test = "0123456789abcdef\n"; 393 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); 410 } 411 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); 417 } 418 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); 423 } 424 MOZ_RELEASE_ASSERT(SIMD::memchr2x8(test, static_cast<char>(count - 2), 425 static_cast<char>(count - 1), 426 count - 1) == nullptr); 427 } 428 429 void TestTinyString2x16() { 430 const char16_t* test = u"012\n"; 431 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); 437 } 438 439 void TestShortString2x16() { 440 const char16_t* test = u"0123456789\n"; 441 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); 453 } 454 455 void TestMediumString2x16() { 456 const char16_t* test = u"0123456789abcdef\n"; 457 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); 475 } 476 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); 482 } 483 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); 488 } 489 MOZ_RELEASE_ASSERT(SIMD::memchr2x16(test, static_cast<char16_t>(count - 2), 490 static_cast<char16_t>(count - 1), 491 count - 1) == nullptr); 492 } 493 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); 500 } 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); 504 } 505 // load in evens and odds sequentially 506 for (size_t i = 0; i < count; ++i) { 507 test[count + i] = static_cast<char>(i); 508 } 509 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; 520 } 521 } 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); 530 } 531 } 532 } 533 } 534 } 535 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); 542 } 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); 546 } 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); 550 } 551 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; 562 } 563 } 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); 572 } 573 } 574 } 575 } 576 } 577 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); 592 } 593 594 int main(void) { 595 TestTinyString(); 596 TestShortString(); 597 TestMediumString(); 598 TestLongString(); 599 TestGauntlet(); 600 601 TestTinyString16(); 602 TestShortString16(); 603 TestMediumString16(); 604 TestLongString16(); 605 TestGauntlet16(); 606 607 TestTinyString64(); 608 TestShortString64(); 609 TestMediumString64(); 610 TestLongString64(); 611 TestGauntlet64(); 612 613 TestTinyString2x8(); 614 TestShortString2x8(); 615 TestMediumString2x8(); 616 TestLongString2x8(); 617 618 TestTinyString2x16(); 619 TestShortString2x16(); 620 TestMediumString2x16(); 621 TestLongString2x16(); 622 623 TestSpecialCases(); 624 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(); 629 630 return 0; 631 }