|
| 1 | +#include <cstring> |
| 2 | +#include <sstream> |
| 3 | + |
1 | 4 | #include "ada/checkers-inl.h" |
2 | 5 | #include "ada/common_defs.h" |
3 | 6 | #include "ada/scheme.h" |
4 | 7 |
|
5 | | -#include <cstring> |
6 | | -#include <sstream> |
7 | | - |
8 | 8 | namespace ada::helpers { |
9 | 9 |
|
10 | 10 | template <typename out_iter> |
@@ -355,6 +355,42 @@ ada_really_inline size_t find_next_host_delimiter_special( |
355 | 355 | } |
356 | 356 | return size_t(view.length()); |
357 | 357 | } |
| 358 | +#elif ADA_RVV |
| 359 | +ada_really_inline size_t find_next_host_delimiter_special( |
| 360 | + std::string_view view, size_t location) noexcept { |
| 361 | + // The LUT approach was a bit slower on the SpacemiT X60, but I could see it |
| 362 | + // beeing faster on future hardware. |
| 363 | +#if 0 |
| 364 | + // LUT generated using: s=":/\\?["; list(zip([((ord(c)>>2)&0xF)for c in s],s)) |
| 365 | + static const uint8_t tbl[16] = { |
| 366 | + 0xF, 0, 0, 0, 0, 0, '[', '\\', 0, 0, 0, '/', 0, 0, ':', '?' |
| 367 | + }; |
| 368 | + vuint8m1_t vtbl = __riscv_vle8_v_u8m1(tbl, 16); |
| 369 | +#endif |
| 370 | + uint8_t* src = (uint8_t*)view.data() + location; |
| 371 | + for (size_t vl, n = view.size() - location; n > 0; |
| 372 | + n -= vl, src += vl, location += vl) { |
| 373 | + vl = __riscv_vsetvl_e8m1(n); |
| 374 | + vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl); |
| 375 | +#if 0 |
| 376 | + vuint8m1_t vidx = __riscv_vand(__riscv_vsrl(v, 2, vl), 0xF, vl); |
| 377 | + vuint8m1_t vlut = __riscv_vrgather(vtbl, vidx, vl); |
| 378 | + vbool8_t m = __riscv_vmseq(v, vlut, vl); |
| 379 | +#else |
| 380 | + vbool8_t m1 = __riscv_vmseq(v, ':', vl); |
| 381 | + vbool8_t m2 = __riscv_vmseq(v, '/', vl); |
| 382 | + vbool8_t m3 = __riscv_vmseq(v, '?', vl); |
| 383 | + vbool8_t m4 = __riscv_vmseq(v, '[', vl); |
| 384 | + vbool8_t m5 = __riscv_vmseq(v, '\\', vl); |
| 385 | + vbool8_t m = __riscv_vmor( |
| 386 | + __riscv_vmor(__riscv_vmor(m1, m2, vl), __riscv_vmor(m3, m4, vl), vl), |
| 387 | + m5, vl); |
| 388 | +#endif |
| 389 | + long idx = __riscv_vfirst(m, vl); |
| 390 | + if (idx >= 0) return location + idx; |
| 391 | + } |
| 392 | + return size_t(view.size()); |
| 393 | +} |
358 | 394 | #else |
359 | 395 | // : / [ \\ ? |
360 | 396 | static constexpr std::array<uint8_t, 256> special_host_delimiters = |
@@ -535,6 +571,25 @@ ada_really_inline size_t find_next_host_delimiter(std::string_view view, |
535 | 571 | } |
536 | 572 | return size_t(view.length()); |
537 | 573 | } |
| 574 | +#elif ADA_RVV |
| 575 | +ada_really_inline size_t find_next_host_delimiter(std::string_view view, |
| 576 | + size_t location) noexcept { |
| 577 | + uint8_t* src = (uint8_t*)view.data() + location; |
| 578 | + for (size_t vl, n = view.size() - location; n > 0; |
| 579 | + n -= vl, src += vl, location += vl) { |
| 580 | + vl = __riscv_vsetvl_e8m1(n); |
| 581 | + vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl); |
| 582 | + vbool8_t m1 = __riscv_vmseq(v, ':', vl); |
| 583 | + vbool8_t m2 = __riscv_vmseq(v, '/', vl); |
| 584 | + vbool8_t m3 = __riscv_vmseq(v, '?', vl); |
| 585 | + vbool8_t m4 = __riscv_vmseq(v, '[', vl); |
| 586 | + vbool8_t m = |
| 587 | + __riscv_vmor(__riscv_vmor(m1, m2, vl), __riscv_vmor(m3, m4, vl), vl); |
| 588 | + long idx = __riscv_vfirst(m, vl); |
| 589 | + if (idx >= 0) return location + idx; |
| 590 | + } |
| 591 | + return size_t(view.size()); |
| 592 | +} |
538 | 593 | #else |
539 | 594 | // : / [ ? |
540 | 595 | static constexpr std::array<uint8_t, 256> host_delimiters = []() consteval { |
|
0 commit comments