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

Function sz_move_sve

include/stringzilla/memory.h:1285–1347  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1283}
1284
1285SZ_PUBLIC void sz_move_sve(sz_ptr_t target, sz_cptr_t source, sz_size_t length) {
1286 sz_size_t vec_len = svcntb(); // Vector length in bytes
1287
1288 // When the buffer is small, there isn't much to innovate.
1289 if (length <= vec_len) {
1290 // Small buffer case: use mask to handle small writes
1291 svbool_t mask = svwhilelt_b8((sz_u64_t)0ull, (sz_u64_t)length);
1292 svuint8_t data = svld1_u8(mask, (sz_u8_t *)source);
1293 svst1_u8(mask, (sz_u8_t *)target, data);
1294 }
1295 // Slightly larger buffers
1296 else if (2 * length <= vec_len) {
1297 svbool_t mask_first = svptrue_b8();
1298 svbool_t mask_second = svwhilelt_b8((sz_u64_t)vec_len, (sz_u64_t)length);
1299 svuint8_t data_first = svld1_u8(mask_first, (sz_u8_t *)(source));
1300 svuint8_t data_second = svld1_u8(mask_second, (sz_u8_t *)(source + vec_len));
1301 svst1_u8(mask_first, (sz_u8_t *)(target), data_first);
1302 svst1_u8(mask_second, (sz_u8_t *)(target + vec_len), data_second);
1303 }
1304 // For medium-sized buffers, check for overlap
1305 else {
1306 // Check if regions overlap with target after source
1307 int const overlapping = (target > source && target < source + length);
1308
1309 if (overlapping) {
1310 // Backward traversal to avoid overwriting source data
1311 source += length;
1312 target += length;
1313
1314 // Backward main loop
1315 for (; length >= vec_len; length -= vec_len) {
1316 source -= vec_len;
1317 target -= vec_len;
1318 svuint8_t data = svld1_u8(svptrue_b8(), (sz_u8_t const *)source);
1319 svst1_u8(svptrue_b8(), (sz_u8_t *)target, data);
1320 }
1321
1322 // Backward tail
1323 if (length) {
1324 source -= length;
1325 target -= length;
1326 svbool_t mask = svwhilelt_b8((sz_u64_t)0ull, (sz_u64_t)length);
1327 svuint8_t data = svld1_u8(mask, (sz_u8_t const *)source);
1328 svst1_u8(mask, (sz_u8_t *)target, data);
1329 }
1330 }
1331 else {
1332 // Forward traversal (safe for non-overlapping or target < source)
1333 // Main loop: full vector copies
1334 for (; length >= vec_len; source += vec_len, target += vec_len, length -= vec_len) {
1335 svuint8_t data = svld1_u8(svptrue_b8(), (sz_u8_t const *)source);
1336 svst1_u8(svptrue_b8(), (sz_u8_t *)target, data);
1337 }
1338
1339 // Tail: single masked copy for remainder
1340 if (length) {
1341 svbool_t mask = svwhilelt_b8((sz_u64_t)0ull, (sz_u64_t)length);
1342 svuint8_t data = svld1_u8(mask, (sz_u8_t const *)source);

Callers 1

sz_moveFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…