numam-dpdk/lib/lpm/rte_lpm_neon.h
Bruce Richardson 99a2dd955f lib: remove librte_ prefix from directory names
There is no reason for the DPDK libraries to all have 'librte_' prefix on
the directory names. This prefix makes the directory names longer and also
makes it awkward to add features referring to individual libraries in the
build - should the lib names be specified with or without the prefix.
Therefore, we can just remove the library prefix and use the library's
unique name as the directory name, i.e. 'eal' rather than 'librte_eal'

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
2021-04-21 14:04:09 +02:00

121 lines
3.3 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2015 Cavium, Inc.
* Copyright(c) 2010-2014 Intel Corporation.
*/
#ifndef _RTE_LPM_NEON_H_
#define _RTE_LPM_NEON_H_
#include <rte_branch_prediction.h>
#include <rte_byteorder.h>
#include <rte_common.h>
#include <rte_vect.h>
#ifdef __cplusplus
extern "C" {
#endif
static inline void
rte_lpm_lookupx4(const struct rte_lpm *lpm, xmm_t ip, uint32_t hop[4],
uint32_t defv)
{
uint32x4_t i24;
rte_xmm_t i8;
uint32_t tbl[4];
uint64_t idx, pt, pt2;
const uint32_t *ptbl;
const uint32_t mask = UINT8_MAX;
const int32x4_t mask8 = vdupq_n_s32(mask);
/*
* RTE_LPM_VALID_EXT_ENTRY_BITMASK for 2 LPM entries
* as one 64-bit value (0x0300000003000000).
*/
const uint64_t mask_xv =
((uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK |
(uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK << 32);
/*
* RTE_LPM_LOOKUP_SUCCESS for 2 LPM entries
* as one 64-bit value (0x0100000001000000).
*/
const uint64_t mask_v =
((uint64_t)RTE_LPM_LOOKUP_SUCCESS |
(uint64_t)RTE_LPM_LOOKUP_SUCCESS << 32);
/* get 4 indexes for tbl24[]. */
i24 = vshrq_n_u32((uint32x4_t)ip, CHAR_BIT);
/* extract values from tbl24[] */
idx = vgetq_lane_u64((uint64x2_t)i24, 0);
ptbl = (const uint32_t *)&lpm->tbl24[(uint32_t)idx];
tbl[0] = *ptbl;
ptbl = (const uint32_t *)&lpm->tbl24[idx >> 32];
tbl[1] = *ptbl;
idx = vgetq_lane_u64((uint64x2_t)i24, 1);
ptbl = (const uint32_t *)&lpm->tbl24[(uint32_t)idx];
tbl[2] = *ptbl;
ptbl = (const uint32_t *)&lpm->tbl24[idx >> 32];
tbl[3] = *ptbl;
/* get 4 indexes for tbl8[]. */
i8.x = vandq_s32(ip, mask8);
pt = (uint64_t)tbl[0] |
(uint64_t)tbl[1] << 32;
pt2 = (uint64_t)tbl[2] |
(uint64_t)tbl[3] << 32;
/* search successfully finished for all 4 IP addresses. */
if (likely((pt & mask_xv) == mask_v) &&
likely((pt2 & mask_xv) == mask_v)) {
*(uint64_t *)hop = pt & RTE_LPM_MASKX4_RES;
*(uint64_t *)(hop + 2) = pt2 & RTE_LPM_MASKX4_RES;
return;
}
if (unlikely((pt & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
i8.u32[0] = i8.u32[0] +
(tbl[0] & 0x00FFFFFF) * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[0]];
tbl[0] = *ptbl;
}
if (unlikely((pt >> 32 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
i8.u32[1] = i8.u32[1] +
(tbl[1] & 0x00FFFFFF) * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[1]];
tbl[1] = *ptbl;
}
if (unlikely((pt2 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
i8.u32[2] = i8.u32[2] +
(tbl[2] & 0x00FFFFFF) * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[2]];
tbl[2] = *ptbl;
}
if (unlikely((pt2 >> 32 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
i8.u32[3] = i8.u32[3] +
(tbl[3] & 0x00FFFFFF) * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[3]];
tbl[3] = *ptbl;
}
hop[0] = (tbl[0] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[0] & 0x00FFFFFF : defv;
hop[1] = (tbl[1] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[1] & 0x00FFFFFF : defv;
hop[2] = (tbl[2] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[2] & 0x00FFFFFF : defv;
hop[3] = (tbl[3] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[3] & 0x00FFFFFF : defv;
}
#ifdef __cplusplus
}
#endif
#endif /* _RTE_LPM_NEON_H_ */