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