xref: /dpdk/examples/common/neon/port_group.h (revision 7f2a987ca852a45bdb4520edc7ad7e02c4efd269)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016-2018 Intel Corporation.
3  * Copyright(c) 2017-2018 Linaro Limited.
4  * Copyright(C) 2022 Marvell.
5  */
6 
7 #ifndef PORT_GROUP_H
8 #define PORT_GROUP_H
9 
10 #include "pkt_group.h"
11 
12 /*
13  * Group consecutive packets with the same destination port in bursts of 4.
14  * Suppose we have array of destination ports:
15  * dst_port[] = {a, b, c, d,, e, ... }
16  * dp1 should contain: <a, b, c, d>, dp2: <b, c, d, e>.
17  * We doing 4 comparisons at once and the result is 4 bit mask.
18  * This mask is used as an index into prebuild array of pnum values.
19  */
20 static inline uint16_t *
21 port_groupx4(uint16_t pn[FWDSTEP + 1], uint16_t *lp, uint16x8_t dp1,
22 		  uint16x8_t dp2)
23 {
24 	union __rte_packed_begin {
25 		uint16_t u16[FWDSTEP + 1];
26 		uint64_t u64;
27 	} __rte_packed_end (*pnum) = (void *)pn;
28 
29 	uint16x8_t mask = {1, 2, 4, 8, 0, 0, 0, 0};
30 	int32_t v;
31 
32 	dp1 = vceqq_u16(dp1, dp2);
33 	dp1 = vandq_u16(dp1, mask);
34 	v = vaddvq_u16(dp1);
35 
36 	/* update last port counter. */
37 	lp[0] += gptbl[v].lpv;
38 	rte_compiler_barrier();
39 
40 	/* if dest port value has changed. */
41 	if (v != GRPMSK) {
42 		pnum->u64 = gptbl[v].pnum;
43 		pnum->u16[FWDSTEP] = 1;
44 		lp = pnum->u16 + gptbl[v].idx;
45 	}
46 
47 	return lp;
48 }
49 
50 #endif /* PORT_GROUP_H */
51