The lookup loaded 64-bit words and shifted the entry out of them. That takes LMUL=8 values whatever the next hop size, one register group more than there is, so a group was spilled inside the loop. Gather the entries at the size they are stored with instead.
Signed-off-by: Sun Yuechi <[email protected]> --- lib/fib/dir24_8_rvv.c | 85 ++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/lib/fib/dir24_8_rvv.c b/lib/fib/dir24_8_rvv.c index 9c14ca0481..9b784bb3c5 100644 --- a/lib/fib/dir24_8_rvv.c +++ b/lib/fib/dir24_8_rvv.c @@ -10,55 +10,64 @@ #include "dir24_8.h" #include "dir24_8_rvv.h" -#define DECLARE_VECTOR_FN(SFX, NH_SZ) \ +/* Byte offset of entry number idx, for each next hop size. */ +#define OFS_1b(idx, vl) ((void)(vl), (idx)) +#define OFS_2b(idx, vl) __riscv_vsll_vx_u32m4(idx, 1, vl) +#define OFS_4b(idx, vl) __riscv_vsll_vx_u32m4(idx, 2, vl) +#define OFS_8b(idx, vl) __riscv_vsll_vx_u32m4(idx, 3, vl) + +/* Entry without its low bit, as 32-bit tbl8 group number. */ +#define GRP_1b(ent, vl) \ + __riscv_vzext_vf4_u32m4(__riscv_vsrl_vx_u8m1(ent, 1, vl), vl) +#define GRP_2b(ent, vl) \ + __riscv_vzext_vf2_u32m4(__riscv_vsrl_vx_u16m2(ent, 1, vl), vl) +#define GRP_4b(ent, vl) __riscv_vsrl_vx_u32m4(ent, 1, vl) +#define GRP_8b(ent, vl) __riscv_vnsrl_wx_u32m4(ent, 1, vl) + +/* Entry without its low bit, as 64-bit next hop. */ +#define NH_1b(ent, vl) \ + __riscv_vzext_vf8_u64m8(__riscv_vsrl_vx_u8m1(ent, 1, vl), vl) +#define NH_2b(ent, vl) \ + __riscv_vzext_vf4_u64m8(__riscv_vsrl_vx_u16m2(ent, 1, vl), vl) +#define NH_4b(ent, vl) \ + __riscv_vzext_vf2_u64m8(__riscv_vsrl_vx_u32m4(ent, 1, vl), vl) +#define NH_8b(ent, vl) __riscv_vsrl_vx_u64m8(ent, 1, vl) + +/* Entries are gathered at their own width, with 32-bit byte offsets. */ +#define DECLARE_VECTOR_FN(SFX, TYPE, BITS, LMUL) \ void \ rte_dir24_8_vec_lookup_bulk_##SFX(void *p, \ const uint32_t *ips, uint64_t *next_hops, unsigned int n) \ { \ - const uint8_t idx_bits = 3 - NH_SZ; \ - const uint32_t idx_mask = (1u << (3 - NH_SZ)) - 1u; \ - const uint64_t e_mask = ~0ULL >> (64 - (8u << NH_SZ)); \ - struct dir24_8_tbl *tbl = (struct dir24_8_tbl *)p; \ - const uint64_t *tbl24 = tbl->tbl24; \ + const struct dir24_8_tbl *tbl = (const struct dir24_8_tbl *)p; \ + const TYPE *tbl24 = (const TYPE *)tbl->tbl24; \ + const TYPE *tbl8 = (const TYPE *)tbl->tbl8; \ size_t vl; \ for (unsigned int i = 0; i < n; i += vl) { \ vl = __riscv_vsetvl_e32m4(n - i); \ vuint32m4_t v_ips = __riscv_vle32_v_u32m4(&ips[i], vl); \ - vuint64m8_t vtbl_word = __riscv_vluxei32_v_u64m8(tbl24, \ - __riscv_vsll_vx_u32m4( \ - __riscv_vsrl_vx_u32m4(v_ips, idx_bits + 8, vl), 3, vl), vl); \ - vuint32m4_t v_tbl_index = __riscv_vsrl_vx_u32m4(v_ips, 8, vl); \ - vuint32m4_t v_entry_idx = __riscv_vand_vx_u32m4(v_tbl_index, idx_mask, vl); \ - vuint32m4_t v_shift = __riscv_vsll_vx_u32m4(v_entry_idx, 3 + NH_SZ, vl); \ - vuint64m8_t vtbl_entry = __riscv_vand_vx_u64m8( \ - __riscv_vsrl_vv_u64m8(vtbl_word, \ - __riscv_vwcvtu_x_x_v_u64m8(v_shift, vl), vl), e_mask, vl); \ - vbool8_t mask = __riscv_vmseq_vx_u64m8_b8( \ - __riscv_vand_vx_u64m8(vtbl_entry, 1, vl), 1, vl); \ - if (__riscv_vcpop_m_b8(mask, vl)) { \ - const uint64_t *tbl8 = tbl->tbl8; \ - v_tbl_index = __riscv_vadd_vv_u32m4_mu(mask, v_tbl_index, \ - __riscv_vsll_vx_u32m4( \ - __riscv_vnsrl_wx_u32m4(vtbl_entry, 1, vl), 8, vl), \ - __riscv_vand_vx_u32m4(v_ips, 0xFF, vl), vl); \ - vtbl_word = __riscv_vluxei32_v_u64m8_mu(mask, vtbl_word, tbl8, \ - __riscv_vsll_vx_u32m4( \ - __riscv_vsrl_vx_u32m4(v_tbl_index, idx_bits, vl), 3, vl), \ - vl); \ - v_entry_idx = __riscv_vand_vx_u32m4(v_tbl_index, idx_mask, vl); \ - v_shift = __riscv_vsll_vx_u32m4(v_entry_idx, 3 + NH_SZ, vl); \ - vtbl_entry = __riscv_vand_vx_u64m8( \ - __riscv_vsrl_vv_u64m8(vtbl_word, \ - __riscv_vwcvtu_x_x_v_u64m8(v_shift, vl), vl), e_mask, vl); \ + vuint##BITS##m##LMUL##_t v_ent = \ + __riscv_vluxei32_v_u##BITS##m##LMUL(tbl24, \ + OFS_##SFX(__riscv_vsrl_vx_u32m4(v_ips, 8, vl), \ + vl), vl); \ + vbool8_t mask = __riscv_vmsne_vx_u##BITS##m##LMUL##_b8( \ + __riscv_vand_vx_u##BITS##m##LMUL(v_ent, \ + DIR24_8_EXT_ENT, vl), 0, vl); \ + if (unlikely(__riscv_vfirst_m_b8(mask, vl) >= 0)) { \ + vuint32m4_t v_idx = __riscv_vadd_vv_u32m4( \ + __riscv_vsll_vx_u32m4(GRP_##SFX(v_ent, vl), \ + 8, vl), \ + __riscv_vand_vx_u32m4(v_ips, 0xFF, vl), vl); \ + v_ent = __riscv_vluxei32_v_u##BITS##m##LMUL##_mu(mask, \ + v_ent, tbl8, OFS_##SFX(v_idx, vl), vl); \ } \ - __riscv_vse64_v_u64m8(&next_hops[i], \ - __riscv_vsrl_vx_u64m8(vtbl_entry, 1, vl), vl); \ + __riscv_vse64_v_u64m8(&next_hops[i], NH_##SFX(v_ent, vl), vl); \ } \ } -DECLARE_VECTOR_FN(1b, 0) -DECLARE_VECTOR_FN(2b, 1) -DECLARE_VECTOR_FN(4b, 2) -DECLARE_VECTOR_FN(8b, 3) +DECLARE_VECTOR_FN(1b, uint8_t, 8, 1) +DECLARE_VECTOR_FN(2b, uint16_t, 16, 2) +DECLARE_VECTOR_FN(4b, uint32_t, 32, 4) +DECLARE_VECTOR_FN(8b, uint64_t, 64, 8) #endif -- 2.56.0

