xref: /dpdk/lib/lpm/rte_lpm_sve.h (revision b29ccbea24ae3a6da4ff3769c4fe702b0702a4b5)
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_compat.h>
9 #include <rte_vect.h>
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 static inline int
__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;
20 	uint64_t vl = svcntw();
21 	svuint32_t v_ip, v_idx, v_tbl24, v_tbl8;
22 	svuint32_t v_mask_xv, v_mask_v;
23 	svbool_t pg = svptrue_b32();
24 	svbool_t pv;
25 
26 	for (i = 0; i < n; i++)
27 		next_hops[i] = 0;
28 
29 	for (i = 0; i < n - vl; i += vl) {
30 		v_ip = svld1(pg, &ips[i]);
31 		/* Get indices for tbl24[] */
32 		v_idx = svlsr_x(pg, v_ip, 8);
33 		/* Extract values from tbl24[] */
34 		v_tbl24 = svld1_gather_index(pg, (const uint32_t *)lpm->tbl24,
35 						v_idx);
36 
37 		/* Create mask with valid set */
38 		v_mask_v = svdup_u32_z(pg, RTE_LPM_LOOKUP_SUCCESS);
39 		/* Create mask with valid and valid_group set */
40 		v_mask_xv = svdup_u32_z(pg, RTE_LPM_VALID_EXT_ENTRY_BITMASK);
41 		/* Create predicate for tbl24 entries: (valid && !valid_group) */
42 		pv = svcmpeq(pg, svand_z(pg, v_tbl24, v_mask_xv), v_mask_v);
43 		svst1(pv, &next_hops[i], v_tbl24);
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 		if (svptest_any(pg, pv)) {
48 			/* Compute tbl8 index */
49 			v_idx = svand_x(pv, v_tbl24, svdup_u32_z(pv, 0xffffff));
50 			v_idx = svmul_x(pv, v_idx, RTE_LPM_TBL8_GROUP_NUM_ENTRIES);
51 			v_idx = svadd_x(pv, svand_x(pv, v_ip, svdup_u32_z(pv, 0xff)),
52 					v_idx);
53 			/* Extract values from tbl8[] */
54 			v_tbl8 = svld1_gather_index(pv, (const uint32_t *)lpm->tbl8,
55 							v_idx);
56 			/* Update predicate for tbl8 entries: (valid) */
57 			pv = svcmpeq(pv, svand_z(pv, v_tbl8, v_mask_v), v_mask_v);
58 			svst1(pv, &next_hops[i], v_tbl8);
59 		}
60 	}
61 
62 	pg = svwhilelt_b32(i, n);
63 	if (svptest_any(svptrue_b32(), pg)) {
64 		v_ip = svld1(pg, &ips[i]);
65 		/* Get indices for tbl24[] */
66 		v_idx = svlsr_x(pg, v_ip, 8);
67 		/* Extract values from tbl24[] */
68 		v_tbl24 = svld1_gather_index(pg, (const uint32_t *)lpm->tbl24,
69 						v_idx);
70 
71 		/* Create mask with valid set */
72 		v_mask_v = svdup_u32_z(pg, RTE_LPM_LOOKUP_SUCCESS);
73 		/* Create mask with valid and valid_group set */
74 		v_mask_xv = svdup_u32_z(pg, RTE_LPM_VALID_EXT_ENTRY_BITMASK);
75 		/* Create predicate for tbl24 entries: (valid && !valid_group) */
76 		pv = svcmpeq(pg, svand_z(pg, v_tbl24, v_mask_xv), v_mask_v);
77 		svst1(pv, &next_hops[i], v_tbl24);
78 
79 		/* Update predicate for tbl24 entries: (valid && valid_group) */
80 		pv = svcmpeq(pg, svand_z(pg, v_tbl24, v_mask_xv), v_mask_xv);
81 		if (svptest_any(pg, pv)) {
82 			/* Compute tbl8 index */
83 			v_idx = svand_x(pv, v_tbl24, svdup_u32_z(pv, 0xffffff));
84 			v_idx = svmul_x(pv, v_idx, RTE_LPM_TBL8_GROUP_NUM_ENTRIES);
85 			v_idx = svadd_x(pv, svand_x(pv, v_ip, svdup_u32_z(pv, 0xff)),
86 					v_idx);
87 			/* Extract values from tbl8[] */
88 			v_tbl8 = svld1_gather_index(pv, (const uint32_t *)lpm->tbl8,
89 							v_idx);
90 			/* Update predicate for tbl8 entries: (valid) */
91 			pv = svcmpeq(pv, svand_z(pv, v_tbl8, v_mask_v), v_mask_v);
92 			svst1(pv, &next_hops[i], v_tbl8);
93 		}
94 	}
95 
96 	return 0;
97 }
98 #ifdef __cplusplus
99 }
100 #endif
101 
102 #endif /* _RTE_LPM_SVE_H_ */
103