xref: /dpdk/lib/table/rte_lru_arm64.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2017 Cavium, Inc
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #ifndef __RTE_LRU_ARM64_H__
699a2dd95SBruce Richardson #define __RTE_LRU_ARM64_H__
799a2dd95SBruce Richardson 
899a2dd95SBruce Richardson #include <stdint.h>
999a2dd95SBruce Richardson #include <rte_vect.h>
10de0ec3c2STyler Retzlaff #include <rte_bitops.h>
1199a2dd95SBruce Richardson 
12*719834a6SMattias Rönnblom #ifdef __cplusplus
13*719834a6SMattias Rönnblom extern "C" {
14*719834a6SMattias Rönnblom #endif
15*719834a6SMattias Rönnblom 
1699a2dd95SBruce Richardson #ifndef RTE_TABLE_HASH_LRU_STRATEGY
1799a2dd95SBruce Richardson #ifdef __ARM_NEON
1899a2dd95SBruce Richardson #define RTE_TABLE_HASH_LRU_STRATEGY                        3
1999a2dd95SBruce Richardson #else /* if no NEON, use simple scalar version */
2099a2dd95SBruce Richardson #define RTE_TABLE_HASH_LRU_STRATEGY                        1
2199a2dd95SBruce Richardson #endif
2299a2dd95SBruce Richardson #endif
2399a2dd95SBruce Richardson 
2499a2dd95SBruce Richardson #if RTE_TABLE_HASH_LRU_STRATEGY == 3
2599a2dd95SBruce Richardson 
2699a2dd95SBruce Richardson #define lru_init(bucket)						\
2799a2dd95SBruce Richardson 	{ bucket->lru_list = ~0LLU; }
2899a2dd95SBruce Richardson 
2999a2dd95SBruce Richardson static inline int
3099a2dd95SBruce Richardson f_lru_pos(uint64_t lru_list)
3199a2dd95SBruce Richardson {
3299a2dd95SBruce Richardson 	/* Compare the vector to zero vector */
3399a2dd95SBruce Richardson 	uint16x4_t lru_vec = vld1_u16((uint16_t *)&lru_list);
3499a2dd95SBruce Richardson 	uint16x4_t min_vec = vmov_n_u16(vminv_u16(lru_vec));
3599a2dd95SBruce Richardson 	uint64_t mask = vget_lane_u64(vreinterpret_u64_u16(
3699a2dd95SBruce Richardson 			vceq_u16(min_vec, lru_vec)), 0);
37de0ec3c2STyler Retzlaff 	return rte_clz64(mask) >> 4;
3899a2dd95SBruce Richardson }
3999a2dd95SBruce Richardson #define lru_pos(bucket) f_lru_pos(bucket->lru_list)
4099a2dd95SBruce Richardson 
4199a2dd95SBruce Richardson #define lru_update(bucket, mru_val)					\
4299a2dd95SBruce Richardson do {									\
4399a2dd95SBruce Richardson 	const uint64_t orvals[] = {0xFFFFLLU, 0xFFFFLLU << 16,		\
4499a2dd95SBruce Richardson 		0xFFFFLLU << 32, 0xFFFFLLU << 48, 0LLU};		\
4599a2dd95SBruce Richardson 	const uint64_t decs[] = {0x1000100010001LLU, 0};		\
4699a2dd95SBruce Richardson 	uint64x1_t lru = vdup_n_u64(bucket->lru_list);			\
4799a2dd95SBruce Richardson 	uint64x1_t vdec = vdup_n_u64(decs[mru_val>>2]);			\
4899a2dd95SBruce Richardson 	bucket->lru_list = vget_lane_u64(vreinterpret_u64_u16(		\
4999a2dd95SBruce Richardson 				vsub_u16(vreinterpret_u16_u64(lru),	\
5099a2dd95SBruce Richardson 					vreinterpret_u16_u64(vdec))),	\
5199a2dd95SBruce Richardson 				0);					\
5299a2dd95SBruce Richardson 	bucket->lru_list |= orvals[mru_val];				\
5399a2dd95SBruce Richardson } while (0)
5499a2dd95SBruce Richardson 
5599a2dd95SBruce Richardson #endif
5699a2dd95SBruce Richardson 
5799a2dd95SBruce Richardson #ifdef __cplusplus
5899a2dd95SBruce Richardson }
5999a2dd95SBruce Richardson #endif
6099a2dd95SBruce Richardson 
6199a2dd95SBruce Richardson #endif
62