MCPcopy Create free account
hub / github.com/ashvardanian/StringZilla / sz_lookup_sve

Function sz_lookup_sve

include/stringzilla/memory.h:1349–1413  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1347}
1348
1349SZ_PUBLIC void sz_lookup_sve(sz_ptr_t target, sz_size_t length, sz_cptr_t source, char const lut[sz_at_least_(256)]) {
1350
1351 if (length <= 128) {
1352 sz_lookup_serial(target, length, source, lut);
1353 return;
1354 }
1355
1356 // SVE vector length in bytes
1357 sz_size_t vl = svcntb();
1358
1359 // Load the 256-byte lookup table into 4 SVE vectors
1360 svuint8_t lut_0_to_63_vec = svld1_u8(svptrue_b8(), (sz_u8_t const *)(lut + 0));
1361 svuint8_t lut_64_to_127_vec = svld1_u8(svptrue_b8(), (sz_u8_t const *)(lut + 64));
1362 svuint8_t lut_128_to_191_vec = svld1_u8(svptrue_b8(), (sz_u8_t const *)(lut + 128));
1363 svuint8_t lut_192_to_255_vec = svld1_u8(svptrue_b8(), (sz_u8_t const *)(lut + 192));
1364
1365 svuint8_t mask_0x3f = svdup_u8(0x3f);
1366
1367 sz_size_t i = 0;
1368
1369 // Main loop: process full vectors
1370 while (i + vl <= length) {
1371 svuint8_t source_vec = svld1_u8(svptrue_b8(), (sz_u8_t const *)(source + i));
1372
1373 // Create predicates based on top 2 bits (which 64-byte range)
1374 svbool_t pred_0_63 = svcmplt_n_u8(svptrue_b8(), source_vec, 64);
1375 svbool_t pred_64_127 = svcmpge_n_u8(svcmplt_n_u8(svptrue_b8(), source_vec, 128), source_vec, 64);
1376 svbool_t pred_128_191 = svcmpge_n_u8(svcmplt_n_u8(svptrue_b8(), source_vec, 192), source_vec, 128);
1377 svbool_t pred_192_255 = svcmpge_n_u8(svptrue_b8(), source_vec, 192);
1378
1379 // Mask indices to bottom 6 bits for indexing within each 64-byte table
1380 svuint8_t idx = svand_u8_x(svptrue_b8(), source_vec, mask_0x3f);
1381
1382 // Perform lookups and blend results based on predicates
1383 svuint8_t result = svsel_u8(pred_0_63, svtbl_u8(lut_0_to_63_vec, idx), svdup_u8(0));
1384 result = svsel_u8(pred_64_127, svtbl_u8(lut_64_to_127_vec, idx), result);
1385 result = svsel_u8(pred_128_191, svtbl_u8(lut_128_to_191_vec, idx), result);
1386 result = svsel_u8(pred_192_255, svtbl_u8(lut_192_to_255_vec, idx), result);
1387
1388 svst1_u8(svptrue_b8(), (sz_u8_t *)target + i, result);
1389 i += vl;
1390 }
1391
1392 // Handle tail: process remaining elements with predicated operations
1393 if (i < length) {
1394 svbool_t pred = svwhilelt_b8_u64(i, length);
1395 svuint8_t source_vec = svld1_u8(pred, (sz_u8_t const *)(source + i));
1396
1397 // Create predicates for each range (comparison already uses pred as governing predicate)
1398 svbool_t pred_0_63 = svcmplt_n_u8(pred, source_vec, 64);
1399 svbool_t pred_64_127 = svcmpge_n_u8(svcmplt_n_u8(pred, source_vec, 128), source_vec, 64);
1400 svbool_t pred_128_191 = svcmpge_n_u8(svcmplt_n_u8(pred, source_vec, 192), source_vec, 128);
1401 svbool_t pred_192_255 = svcmpge_n_u8(pred, source_vec, 192);
1402
1403 // Mask indices to bottom 6 bits
1404 svuint8_t idx = svand_u8_x(pred, source_vec, mask_0x3f);
1405
1406 svuint8_t result = svsel_u8(pred_0_63, svtbl_u8(lut_0_to_63_vec, idx), svdup_u8(0));

Callers 1

sz_lookupFunction · 0.85

Calls 1

sz_lookup_serialFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…