xref: /dpdk/lib/lpm/rte_lpm_sve.h (revision 99a2dd95)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Arm Limited
3  */
4 
5 #ifndef _RTE_LPM_SVE_H_
6 #define _RTE_LPM_SVE_H_
7 
8 #include <rte_vect.h>
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 __rte_internal
15 static void
__rte_lpm_lookup_vec(const struct rte_lpm * lpm,const uint32_t * ips,uint32_t * __rte_restrict next_hops,const uint32_t n)16 __rte_lpm_lookup_vec(const struct rte_lpm *lpm, const uint32_t *ips,
17 		uint32_t *__rte_restrict next_hops, const uint32_t n)
18 {
19 	uint32_t i = 0;
20 	svuint32_t v_ip, v_idx, v_tbl24, v_tbl8, v_hop;
21 	svuint32_t v_mask_xv, v_mask_v, v_mask_hop;
22 	svbool_t pg = svwhilelt_b32(i, n);
23 	svbool_t pv;
24 
25 	do {
26 		v_ip = svld1(pg, &ips[i]);
27 		/* Get indices for tbl24[] */
28 		v_idx = svlsr_x(pg, v_ip, 8);
29 		/* Extract values from tbl24[] */
30 		v_tbl24 = svld1_gather_index(pg, (const uint32_t *)lpm->tbl24,
31 						v_idx);
32 
33 		/* Create mask with valid set */
34 		v_mask_v = svdup_u32_z(pg, RTE_LPM_LOOKUP_SUCCESS);
35 		/* Create mask with valid and valid_group set */
36 		v_mask_xv = svdup_u32_z(pg, RTE_LPM_VALID_EXT_ENTRY_BITMASK);
37 		/* Create predicate for tbl24 entries: (valid && !valid_group) */
38 		pv = svcmpeq(pg, svand_z(pg, v_tbl24, v_mask_xv), v_mask_v);
39 		/* Create mask for next_hop in table entry */
40 		v_mask_hop = svdup_u32_z(pg, 0x00ffffff);
41 		/* Extract next_hop and write back */
42 		v_hop = svand_x(pv, v_tbl24, v_mask_hop);
43 		svst1(pv, &next_hops[i], v_hop);
44 
45 		/* Update predicate for tbl24 entries: (valid && valid_group) */
46 		pv = svcmpeq(pg, svand_z(pg, v_tbl24, v_mask_xv), v_mask_xv);
47 		/* Compute tbl8 index */
48 		v_idx = svand_x(pv, v_tbl24, svdup_u32_z(pv, 0xffffff));
49 		v_idx = svmul_x(pv, v_idx, RTE_LPM_TBL8_GROUP_NUM_ENTRIES);
50 		v_idx = svadd_x(pv, svand_x(pv, v_ip, svdup_u32_z(pv, 0xff)),
51 				v_idx);
52 		/* Extract values from tbl8[] */
53 		v_tbl8 = svld1_gather_index(pv, (const uint32_t *)lpm->tbl8,
54 						v_idx);
55 		/* Update predicate for tbl8 entries: (valid) */
56 		pv = svcmpeq(pv, svand_z(pv, v_tbl8, v_mask_v), v_mask_v);
57 		/* Extract next_hop and write back */
58 		v_hop = svand_x(pv, v_tbl8, v_mask_hop);
59 		svst1(pv, &next_hops[i], v_hop);
60 
61 		i += svlen(v_ip);
62 		pg = svwhilelt_b32(i, n);
63 	} while (svptest_any(svptrue_b32(), pg));
64 }
65 
66 static inline void
rte_lpm_lookupx4(const struct rte_lpm * lpm,xmm_t ip,uint32_t hop[4],uint32_t defv)67 rte_lpm_lookupx4(const struct rte_lpm *lpm, xmm_t ip, uint32_t hop[4],
68 		uint32_t defv)
69 {
70 	uint32_t i, ips[4];
71 
72 	vst1q_s32((int32_t *)ips, ip);
73 	for (i = 0; i < 4; i++)
74 		hop[i] = defv;
75 
76 	__rte_lpm_lookup_vec(lpm, ips, hop, 4);
77 }
78 
79 #ifdef __cplusplus
80 }
81 #endif
82 
83 #endif /* _RTE_LPM_SVE_H_ */
84