| 1347 | } |
| 1348 | |
| 1349 | SZ_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)); |
no test coverage detected
searching dependent graphs…