Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2020 Intel Corporation
3 : : */
4 : :
5 : : /*
6 : : * WARNING: It is not recommended to include this file directly.
7 : : * Please include "acl_run_avx512x*.h" instead.
8 : : * To make this file to generate proper code an includer has to
9 : : * define several macros, refer to "acl_run_avx512x*.h" for more details.
10 : : */
11 : :
12 : : /*
13 : : * Calculate the address of the next transition for
14 : : * all types of nodes. Note that only DFA nodes and range
15 : : * nodes actually transition to another node. Match
16 : : * nodes not supposed to be encountered here.
17 : : * For quad range nodes:
18 : : * Calculate number of range boundaries that are less than the
19 : : * input value. Range boundaries for each node are in signed 8 bit,
20 : : * ordered from -128 to 127.
21 : : * This is effectively a popcnt of bytes that are greater than the
22 : : * input byte.
23 : : * Single nodes are processed in the same ways as quad range nodes.
24 : : */
25 : : static __rte_always_inline _T_simd
26 : : _F_(calc_addr)(_T_simd index_mask, _T_simd next_input, _T_simd shuffle_input,
27 : : _T_simd four_32, _T_simd range_base, _T_simd tr_lo, _T_simd tr_hi)
28 : : {
29 : : __mmask64 qm;
30 : : _T_mask dfa_msk;
31 : : _T_simd addr, in, node_type, r, t;
32 : : _T_simd dfa_ofs, quad_ofs;
33 : :
34 : : t = _M_SI_(xor)(index_mask, index_mask);
35 : : in = _M_I_(shuffle_epi8)(next_input, shuffle_input);
36 : :
37 : : /* Calc node type and node addr */
38 : : node_type = _M_SI_(andnot)(index_mask, tr_lo);
39 : : addr = _M_SI_(and)(index_mask, tr_lo);
40 : :
41 : : /* mask for DFA type(0) nodes */
42 : : dfa_msk = _M_I_(cmpeq_epi32_mask)(node_type, t);
43 : :
44 : : /* DFA calculations. */
45 : : r = _M_I_(srli_epi32)(in, 30);
46 : : r = _M_I_(add_epi8)(r, range_base);
47 : : t = _M_I_(srli_epi32)(in, 24);
48 : : r = _M_I_(shuffle_epi8)(tr_hi, r);
49 : :
50 : : dfa_ofs = _M_I_(sub_epi32)(t, r);
51 : :
52 : : /* QUAD/SINGLE calculations. */
53 : : qm = _M_I_(cmpgt_epi8_mask)(in, tr_hi);
54 : : t = _M_I_(maskz_set1_epi8)(qm, (uint8_t)UINT8_MAX);
55 : : t = _M_I_(lzcnt_epi32)(t);
56 : : t = _M_I_(srli_epi32)(t, 3);
57 : : quad_ofs = _M_I_(sub_epi32)(four_32, t);
58 : :
59 : : /* blend DFA and QUAD/SINGLE. */
60 : 1811612 : t = _M_I_(mask_mov_epi32)(quad_ofs, dfa_msk, dfa_ofs);
61 : :
62 : : /* calculate address for next transitions. */
63 : : addr = _M_I_(add_epi32)(addr, t);
64 : : return addr;
65 : : }
66 : :
67 : : /*
68 : : * Process _N_ transitions in parallel.
69 : : * tr_lo contains low 32 bits for _N_ transition.
70 : : * tr_hi contains high 32 bits for _N_ transition.
71 : : * next_input contains up to 4 input bytes for _N_ flows.
72 : : */
73 : : static __rte_always_inline _T_simd
74 : : _F_(trans)(_T_simd next_input, const uint64_t *trans, _T_simd *tr_lo,
75 : : _T_simd *tr_hi)
76 : : {
77 : : const int32_t *tr;
78 : : _T_simd addr;
79 : :
80 : : tr = (const int32_t *)(uintptr_t)trans;
81 : :
82 : : /* Calculate the address (array index) for all _N_ transitions. */
83 : 1811612 : addr = _F_(calc_addr)(_SV_(index_mask), next_input, _SV_(shuffle_input),
84 : : _SV_(four_32), _SV_(range_base), *tr_lo, *tr_hi);
85 : :
86 : : /* load lower 32 bits of _N_ transactions at once. */
87 : 1811612 : *tr_lo = _M_GI_(i32gather_epi32, addr, tr, sizeof(trans[0]));
88 : :
89 : : next_input = _M_I_(srli_epi32)(next_input, CHAR_BIT);
90 : :
91 : : /* load high 32 bits of _N_ transactions at once. */
92 : 1811612 : *tr_hi = _M_GI_(i32gather_epi32, addr, (tr + 1), sizeof(trans[0]));
93 : :
94 : : return next_input;
95 : : }
96 : :
97 : : /*
98 : : * Execute first transition for up to _N_ flows in parallel.
99 : : * next_input should contain one input byte for up to _N_ flows.
100 : : * msk - mask of active flows.
101 : : * tr_lo contains low 32 bits for up to _N_ transitions.
102 : : * tr_hi contains high 32 bits for up to _N_ transitions.
103 : : */
104 : : static __rte_always_inline void
105 : : _F_(first_trans)(const struct acl_flow_avx512 *flow, _T_simd next_input,
106 : : _T_mask msk, _T_simd *tr_lo, _T_simd *tr_hi)
107 : : {
108 : : const int32_t *tr;
109 : : _T_simd addr, root;
110 : :
111 : 905236 : tr = (const int32_t *)(uintptr_t)flow->trans;
112 : :
113 : : addr = _M_I_(set1_epi32)(UINT8_MAX);
114 : 905236 : root = _M_I_(set1_epi32)(flow->root_index);
115 : :
116 : : addr = _M_SI_(and)(next_input, addr);
117 : : addr = _M_I_(add_epi32)(root, addr);
118 : :
119 : : /* load lower 32 bits of _N_ transactions at once. */
120 : 701077 : *tr_lo = _M_MGI_(mask_i32gather_epi32)(*tr_lo, msk, addr, tr,
121 : : sizeof(flow->trans[0]));
122 : :
123 : : /* load high 32 bits of _N_ transactions at once. */
124 : 905236 : *tr_hi = _M_MGI_(mask_i32gather_epi32)(*tr_hi, msk, addr, (tr + 1),
125 : : sizeof(flow->trans[0]));
126 : : }
127 : :
128 : : /*
129 : : * Load and return next 4 input bytes for up to _N_ flows in parallel.
130 : : * pdata - 8x2 pointers to flow input data
131 : : * mask - mask of active flows.
132 : : * di - data indexes for these _N_ flows.
133 : : */
134 : : static inline _T_simd
135 : 1109395 : _F_(get_next_bytes)(const struct acl_flow_avx512 *flow, _T_simd pdata[2],
136 : : uint32_t msk, _T_simd *di, uint32_t bnum)
137 : : {
138 : : const int32_t *div;
139 : : uint32_t m[2];
140 : : _T_simd one, zero, t, p[2];
141 : :
142 : 2921007 : div = (const int32_t *)flow->data_index;
143 : :
144 : : one = _M_I_(set1_epi32)(1);
145 : : zero = _M_SI_(xor)(one, one);
146 : :
147 : : /* load data offsets for given indexes */
148 [ - + ]: 2921007 : t = _M_MGI_(mask_i32gather_epi32)(zero, msk, *di, div, sizeof(div[0]));
149 : :
150 : : /* increment data indexes */
151 [ - + ]: 2921007 : *di = _M_I_(mask_add_epi32)(*di, msk, *di, one);
152 : :
153 : : /*
154 : : * unsigned expand 32-bit indexes to 64-bit
155 : : * (for later pointer arithmetic), i.e:
156 : : * for (i = 0; i != _N_; i++)
157 : : * p[i/8].u64[i%8] = (uint64_t)t.u32[i];
158 : : */
159 : : p[0] = _M_I_(maskz_permutexvar_epi32)(_SC_(pmidx_msk), _SV_(pmidx[0]),
160 : : t);
161 : : p[1] = _M_I_(maskz_permutexvar_epi32)(_SC_(pmidx_msk), _SV_(pmidx[1]),
162 : : t);
163 : :
164 [ - + ]: 2921007 : p[0] = _M_I_(add_epi64)(p[0], pdata[0]);
165 : 2921007 : p[1] = _M_I_(add_epi64)(p[1], pdata[1]);
166 : :
167 : : /* load input byte(s), either one or four */
168 : :
169 : 2921007 : m[0] = msk & _SIMD_PTR_MSK_;
170 [ - + ]: 2921007 : m[1] = msk >> _SIMD_PTR_NUM_;
171 : :
172 : 1109395 : return _F_(gather_bytes)(zero, p, m, bnum);
173 : : }
174 : :
175 : : /*
176 : : * Start up to _N_ new flows.
177 : : * num - number of flows to start
178 : : * msk - mask of new flows.
179 : : * pdata - pointers to flow input data
180 : : * idx - match indexed for given flows
181 : : * di - data indexes for these flows.
182 : : */
183 : : static inline void
184 : 1518977 : _F_(start_flow)(struct acl_flow_avx512 *flow, uint32_t num, uint32_t msk,
185 : : _T_simd pdata[2], _T_simd *idx, _T_simd *di)
186 : : {
187 : : uint32_t n, m[2], nm[2];
188 : : _T_simd ni, nd[2];
189 : :
190 : : /* split mask into two - one for each pdata[] */
191 : 1518977 : m[0] = msk & _SIMD_PTR_MSK_;
192 : 1518977 : m[1] = msk >> _SIMD_PTR_NUM_;
193 : :
194 : : /* calculate masks for new flows */
195 : : n = rte_popcount32(m[0]);
196 : 1518977 : nm[0] = (1 << n) - 1;
197 : 1518977 : nm[1] = (1 << (num - n)) - 1;
198 : :
199 : : /* load input data pointers for new flows */
200 : 1518977 : nd[0] = _M_I_(maskz_loadu_epi64)(nm[0],
201 : 1518977 : flow->idata + flow->num_packets);
202 : 1518977 : nd[1] = _M_I_(maskz_loadu_epi64)(nm[1],
203 : 1518977 : flow->idata + flow->num_packets + n);
204 : :
205 : : /* calculate match indexes of new flows */
206 : 1518977 : ni = _M_I_(set1_epi32)(flow->num_packets);
207 : : ni = _M_I_(add_epi32)(ni, _SV_(idx_add));
208 : :
209 : : /* merge new and existing flows data */
210 : 1518977 : pdata[0] = _M_I_(mask_expand_epi64)(pdata[0], m[0], nd[0]);
211 : 1518977 : pdata[1] = _M_I_(mask_expand_epi64)(pdata[1], m[1], nd[1]);
212 : :
213 : : /* update match and data indexes */
214 : 1518977 : *idx = _M_I_(mask_expand_epi32)(*idx, msk, ni);
215 : 1518977 : *di = _M_I_(maskz_mov_epi32)(msk ^ _SIMD_MASK_MAX_, *di);
216 : :
217 : 1518977 : flow->num_packets += num;
218 : 1518977 : }
219 : :
220 : : /*
221 : : * Process found matches for up to _N_ flows.
222 : : * fmsk - mask of active flows
223 : : * rmsk - mask of found matches
224 : : * pdata - pointers to flow input data
225 : : * di - data indexes for these flows
226 : : * idx - match indexed for given flows
227 : : * tr_lo contains low 32 bits for up to _N_ transitions.
228 : : * tr_hi contains high 32 bits for up to _N_ transitions.
229 : : */
230 : : static inline uint32_t
231 : 1211332 : _F_(match_process)(struct acl_flow_avx512 *flow, uint32_t *fmsk,
232 : : uint32_t *rmsk, _T_simd pdata[2], _T_simd *di, _T_simd *idx,
233 : : _T_simd *tr_lo, _T_simd *tr_hi)
234 : : {
235 : : uint32_t n;
236 : : _T_simd res;
237 : :
238 [ + + ]: 1211332 : if (rmsk[0] == 0)
239 : : return 0;
240 : :
241 : : /* extract match indexes */
242 : 1110659 : res = _M_SI_(and)(tr_lo[0], _SV_(index_mask));
243 : :
244 : : /* mask matched transitions to nop */
245 : 1110659 : tr_lo[0] = _M_I_(mask_mov_epi32)(tr_lo[0], rmsk[0], _SV_(trlo_idle));
246 : 1110659 : tr_hi[0] = _M_I_(mask_mov_epi32)(tr_hi[0], rmsk[0], _SV_(trhi_idle));
247 : :
248 : : /* save found match indexes */
249 : 1110659 : _M_I_(mask_i32scatter_epi32)((void *)flow->matches, rmsk[0], idx[0],
250 : : res, sizeof(flow->matches[0]));
251 : :
252 : : /* update masks and start new flows for matches */
253 : : n = update_flow_mask(flow, fmsk, rmsk);
254 : 1110659 : _F_(start_flow)(flow, n, rmsk[0], pdata, idx, di);
255 : :
256 : 1110659 : return n;
257 : : }
258 : :
259 : : /*
260 : : * Test for matches ut to (2 * _N_) flows at once,
261 : : * if matches exist - process them and start new flows.
262 : : */
263 : : static inline void
264 : 2015771 : _F_(match_check_process)(struct acl_flow_avx512 *flow, uint32_t fm[2],
265 : : _T_simd pdata[4], _T_simd di[2], _T_simd idx[2], _T_simd inp[2],
266 : : _T_simd tr_lo[2], _T_simd tr_hi[2])
267 : : {
268 : : uint32_t n[2];
269 : : uint32_t rm[2];
270 : :
271 : : /* check for matches */
272 : 2015771 : rm[0] = _M_I_(test_epi32_mask)(tr_lo[0], _SV_(match_mask));
273 : 2015771 : rm[1] = _M_I_(test_epi32_mask)(tr_lo[1], _SV_(match_mask));
274 : :
275 : : /* till unprocessed matches exist */
276 [ + + ]: 4637208 : while ((rm[0] | rm[1]) != 0) {
277 : :
278 : : /* process matches and start new flows */
279 : 605666 : n[0] = _F_(match_process)(flow, &fm[0], &rm[0], &pdata[0],
280 : : &di[0], &idx[0], &tr_lo[0], &tr_hi[0]);
281 : 605666 : n[1] = _F_(match_process)(flow, &fm[1], &rm[1], &pdata[2],
282 : : &di[1], &idx[1], &tr_lo[1], &tr_hi[1]);
283 : :
284 : : /* execute first transition for new flows, if any */
285 : :
286 [ + + ]: 605666 : if (n[0] != 0) {
287 : 400590 : inp[0] = _F_(get_next_bytes)(flow, &pdata[0],
288 : : rm[0], &di[0], flow->first_load_sz);
289 : : _F_(first_trans)(flow, inp[0], rm[0], &tr_lo[0],
290 : : &tr_hi[0]);
291 : 400590 : rm[0] = _M_I_(test_epi32_mask)(tr_lo[0],
292 : : _SV_(match_mask));
293 : : }
294 : :
295 [ + + ]: 605666 : if (n[1] != 0) {
296 : 300487 : inp[1] = _F_(get_next_bytes)(flow, &pdata[2],
297 : : rm[1], &di[1], flow->first_load_sz);
298 : : _F_(first_trans)(flow, inp[1], rm[1], &tr_lo[1],
299 : : &tr_hi[1]);
300 : 300487 : rm[1] = _M_I_(test_epi32_mask)(tr_lo[1],
301 : : _SV_(match_mask));
302 : : }
303 : : }
304 : 2015771 : }
305 : :
306 : : static inline void
307 : : _F_(reset_flow_vars)(_T_simd di[2], _T_simd idx[2], _T_simd pdata[4],
308 : : _T_simd tr_lo[2], _T_simd tr_hi[2])
309 : : {
310 : 204159 : di[0] = _M_SI_(setzero)();
311 : 204159 : di[1] = _M_SI_(setzero)();
312 : :
313 : 204159 : idx[0] = _M_SI_(setzero)();
314 : 204159 : idx[1] = _M_SI_(setzero)();
315 : :
316 : 204159 : pdata[0] = _M_SI_(setzero)();
317 : 204159 : pdata[1] = _M_SI_(setzero)();
318 : 204159 : pdata[2] = _M_SI_(setzero)();
319 : 204159 : pdata[3] = _M_SI_(setzero)();
320 : :
321 : : tr_lo[0] = _M_SI_(setzero)();
322 : : tr_lo[1] = _M_SI_(setzero)();
323 : :
324 : : tr_hi[0] = _M_SI_(setzero)();
325 : : tr_hi[1] = _M_SI_(setzero)();
326 : : }
327 : :
328 : : /*
329 : : * Perform search for up to (2 * _N_) flows in parallel.
330 : : * Use two sets of metadata, each serves _N_ flows max.
331 : : */
332 : : static inline void
333 : 204159 : _F_(search_trie)(struct acl_flow_avx512 *flow)
334 : : {
335 : : uint32_t fm[2];
336 : : _T_simd di[2], idx[2], in[2], pdata[4], tr_lo[2], tr_hi[2];
337 : :
338 : : _F_(reset_flow_vars)(di, idx, pdata, tr_lo, tr_hi);
339 : :
340 : : /* first 1B load */
341 : 204159 : _F_(start_flow)(flow, _SIMD_MASK_BIT_, _SIMD_MASK_MAX_,
342 : : &pdata[0], &idx[0], &di[0]);
343 : 204159 : _F_(start_flow)(flow, _SIMD_MASK_BIT_, _SIMD_MASK_MAX_,
344 : : &pdata[2], &idx[1], &di[1]);
345 : :
346 : 204159 : in[0] = _F_(get_next_bytes)(flow, &pdata[0], _SIMD_MASK_MAX_, &di[0],
347 : : flow->first_load_sz);
348 : 204159 : in[1] = _F_(get_next_bytes)(flow, &pdata[2], _SIMD_MASK_MAX_, &di[1],
349 : : flow->first_load_sz);
350 : :
351 : : _F_(first_trans)(flow, in[0], _SIMD_MASK_MAX_, &tr_lo[0], &tr_hi[0]);
352 : : _F_(first_trans)(flow, in[1], _SIMD_MASK_MAX_, &tr_lo[1], &tr_hi[1]);
353 : :
354 : 204159 : fm[0] = _SIMD_MASK_MAX_;
355 : 204159 : fm[1] = _SIMD_MASK_MAX_;
356 : :
357 : : /* match check */
358 : 204159 : _F_(match_check_process)(flow, fm, pdata, di, idx, in, tr_lo, tr_hi);
359 : :
360 [ + + ]: 2015771 : while ((fm[0] | fm[1]) != 0) {
361 : :
362 : : /* load next 4B */
363 : :
364 : : in[0] = _F_(get_next_bytes)(flow, &pdata[0], fm[0],
365 : : &di[0], sizeof(uint32_t));
366 : : in[1] = _F_(get_next_bytes)(flow, &pdata[2], fm[1],
367 : : &di[1], sizeof(uint32_t));
368 : :
369 : : /* main 4B loop */
370 : :
371 : 1811612 : in[0] = _F_(trans)(in[0], flow->trans, &tr_lo[0], &tr_hi[0]);
372 : : in[1] = _F_(trans)(in[1], flow->trans, &tr_lo[1], &tr_hi[1]);
373 : :
374 : : in[0] = _F_(trans)(in[0], flow->trans, &tr_lo[0], &tr_hi[0]);
375 : : in[1] = _F_(trans)(in[1], flow->trans, &tr_lo[1], &tr_hi[1]);
376 : :
377 : : in[0] = _F_(trans)(in[0], flow->trans, &tr_lo[0], &tr_hi[0]);
378 : : in[1] = _F_(trans)(in[1], flow->trans, &tr_lo[1], &tr_hi[1]);
379 : :
380 : 1811612 : in[0] = _F_(trans)(in[0], flow->trans, &tr_lo[0], &tr_hi[0]);
381 : 1811612 : in[1] = _F_(trans)(in[1], flow->trans, &tr_lo[1], &tr_hi[1]);
382 : :
383 : : /* check for matches */
384 : 1811612 : _F_(match_check_process)(flow, fm, pdata, di, idx, in,
385 : : tr_lo, tr_hi);
386 : : }
387 : 204159 : }
388 : :
389 : : /*
390 : : * resolve match index to actual result/priority offset.
391 : : */
392 : : static inline _T_simd
393 : : _F_(resolve_match_idx)(_T_simd mi)
394 : : {
395 : : RTE_BUILD_BUG_ON(sizeof(struct rte_acl_match_results) !=
396 : : 1 << (ACL_MATCH_LOG + 2));
397 : : return _M_I_(slli_epi32)(mi, ACL_MATCH_LOG);
398 : : }
399 : :
400 : : /*
401 : : * Resolve multiple matches for the same flow based on priority.
402 : : */
403 : : static inline _T_simd
404 : : _F_(resolve_pri)(const int32_t res[], const int32_t pri[],
405 : : const uint32_t match[], _T_mask msk, uint32_t nb_trie,
406 : : uint32_t nb_skip)
407 : : {
408 : : uint32_t i;
409 : : const uint32_t *pm;
410 : : _T_mask m;
411 : : _T_simd cp, cr, np, nr, mch;
412 : :
413 : : const _T_simd zero = _M_I_(set1_epi32)(0);
414 : :
415 : : /* get match indexes */
416 : : mch = _M_I_(maskz_loadu_epi32)(msk, match);
417 : : mch = _F_(resolve_match_idx)(mch);
418 : :
419 : : /* read result and priority values for first trie */
420 : : cr = _M_MGI_(mask_i32gather_epi32)(zero, msk, mch, res, sizeof(res[0]));
421 : : cp = _M_MGI_(mask_i32gather_epi32)(zero, msk, mch, pri, sizeof(pri[0]));
422 : :
423 : : /*
424 : : * read result and priority values for next tries and select one
425 : : * with highest priority.
426 : : */
427 [ # # # # : 0 : for (i = 1, pm = match + nb_skip; i != nb_trie;
# # # # #
# # # # #
# # ]
428 : 0 : i++, pm += nb_skip) {
429 : :
430 : : mch = _M_I_(maskz_loadu_epi32)(msk, pm);
431 : : mch = _F_(resolve_match_idx)(mch);
432 : :
433 : : nr = _M_MGI_(mask_i32gather_epi32)(zero, msk, mch, res,
434 : : sizeof(res[0]));
435 : : np = _M_MGI_(mask_i32gather_epi32)(zero, msk, mch, pri,
436 : : sizeof(pri[0]));
437 : :
438 : : m = _M_I_(cmpgt_epi32_mask)(cp, np);
439 : 0 : cr = _M_I_(mask_mov_epi32)(nr, m, cr);
440 : : cp = _M_I_(mask_mov_epi32)(np, m, cp);
441 : : }
442 : :
443 : : return cr;
444 : : }
445 : :
446 : : /*
447 : : * Resolve num (<= _N_) matches for single category
448 : : */
449 : : static inline void
450 : : _F_(resolve_sc)(uint32_t result[], const int32_t res[],
451 : : const int32_t pri[], const uint32_t match[], uint32_t nb_pkt,
452 : : uint32_t nb_trie, uint32_t nb_skip)
453 : : {
454 : : _T_mask msk;
455 : : _T_simd cr;
456 : :
457 : 0 : msk = (1 << nb_pkt) - 1;
458 : 0 : cr = _F_(resolve_pri)(res, pri, match, msk, nb_trie, nb_skip);
459 : : _M_I_(mask_storeu_epi32)(result, msk, cr);
460 : 0 : }
461 : :
462 : : /*
463 : : * Resolve matches for single category
464 : : */
465 : : static inline void
466 : 0 : _F_(resolve_single_cat)(uint32_t result[],
467 : : const struct rte_acl_match_results pr[], const uint32_t match[],
468 : : uint32_t nb_pkt, uint32_t nb_trie)
469 : : {
470 : : uint32_t j, k, n;
471 : : const int32_t *res, *pri;
472 : : _T_simd cr[2];
473 : :
474 : 0 : res = (const int32_t *)pr->results;
475 : 0 : pri = pr->priority;
476 : :
477 [ # # ]: 0 : for (k = 0; k != (nb_pkt & ~_SIMD_FLOW_MSK_); k += _SIMD_FLOW_NUM_) {
478 : :
479 : 0 : j = k + _SIMD_MASK_BIT_;
480 : :
481 : 0 : cr[0] = _F_(resolve_pri)(res, pri, match + k, _SIMD_MASK_MAX_,
482 : : nb_trie, nb_pkt);
483 : 0 : cr[1] = _F_(resolve_pri)(res, pri, match + j, _SIMD_MASK_MAX_,
484 : : nb_trie, nb_pkt);
485 : :
486 : 0 : _M_SI_(storeu)((void *)(result + k), cr[0]);
487 : 0 : _M_SI_(storeu)((void *)(result + j), cr[1]);
488 : : }
489 : :
490 : 0 : n = nb_pkt - k;
491 [ # # ]: 0 : if (n != 0) {
492 [ # # ]: 0 : if (n > _SIMD_MASK_BIT_) {
493 : 0 : _F_(resolve_sc)(result + k, res, pri, match + k,
494 : : _SIMD_MASK_BIT_, nb_trie, nb_pkt);
495 : 0 : k += _SIMD_MASK_BIT_;
496 : 0 : n -= _SIMD_MASK_BIT_;
497 : : }
498 : 0 : _F_(resolve_sc)(result + k, res, pri, match + k, n,
499 : : nb_trie, nb_pkt);
500 : : }
501 : 0 : }
|