From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from na01-bn1-obe.outbound.protection.outlook.com (mail-bn1on0065.outbound.protection.outlook.com [157.56.110.65]) by dpdk.org (Postfix) with ESMTP id DBB949612 for ; Fri, 12 Feb 2016 13:29:33 +0100 (CET) Authentication-Results: dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=none action=none header.from=caviumnetworks.com; Received: from localhost.localdomain.localdomain (122.167.12.50) by BY1PR0701MB1721.namprd07.prod.outlook.com (10.162.111.140) with Microsoft SMTP Server (TLS) id 15.1.403.16; Fri, 12 Feb 2016 12:29:30 +0000 From: Jerin Jacob To: Date: Fri, 12 Feb 2016 17:58:42 +0530 Message-ID: <1455280123-9311-3-git-send-email-jerin.jacob@caviumnetworks.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1455280123-9311-1-git-send-email-jerin.jacob@caviumnetworks.com> References: <1454040645-23864-1-git-send-email-jerin.jacob@caviumnetworks.com> <1455280123-9311-1-git-send-email-jerin.jacob@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [122.167.12.50] X-ClientProxiedBy: PN1PR01CA0022.INDPRD01.PROD.OUTLOOK.COM (25.164.137.29) To BY1PR0701MB1721.namprd07.prod.outlook.com (25.162.111.140) X-Microsoft-Exchange-Diagnostics: 1; BY1PR0701MB1721; 2:XpdBqNnKeaAJsf1M9SOzNE8AGlcadlXifUh6miDDLCjUTVWfFRN1J47iEwiyolxgAO3oFOQ3EvSSR41wTde1OSx1s9qYHA5TRgwMM7q9i5tjHKHSKWFNLoHSFwp+3OTnFlUr0cAZA7l56tT9W34/EQ==; 3:6g5bspIUF61gnNdBfqzURckUGDoX1cfnbesMcCfMhVcb6yRIZPeF9aUKq4cXAQMLUIXNF8loiUd8YbPMYLL7zuA2F8NAyJGG8S9S9amTRqxiYJXPy2nehOXPMZg8pajW; 25:tydtd+aIcj35oEiwwxqP0xFufjF2byj+W2zEDx25eE5jP2s5ygfgurWLdATCShrDatJeEV0fUfKxMBJFPpCti6LN5G26GKrgeivUztVOF+OUPY5vWqxloYgSN7vZlg88sY2k/DiCu47y6THQErumrT8VH6alqJEQxWWuiiTw6xskO8BEUZ0ULBFspkDHcvc548tILKTvWM5kccxUSsWZIbOxwHmR3Fm4j9y0t6HdlOIpmsKurKBcbXh5illIAvLC6kVk4D24N+pGD5h6dw6yEHV8yk6bVDKYsPJODRuhesZg88nxC8NtBJIlSj1ZkL7W X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY1PR0701MB1721; X-MS-Office365-Filtering-Correlation-Id: fd31ef4f-4d17-4177-1f52-08d333a82918 X-Microsoft-Exchange-Diagnostics: 1; BY1PR0701MB1721; 20:WIy4G9SvFzEKCS+1VMfd/cG36Nco0MuhJp1mUCs5Io2cA0N4xFNtaetXXmNKVbRKHfh5Nakg2RU60smGW93yR4roRnmQeAB7nxBKPAtPKjLMNB9WoIDrpVYiSWMeGb129ABOV4J/Bye4Hthf25ZY4slwYwgUHeHbOavfm4dMwVukuxyOizFp8SxbEeB/ZW0JxjrRPDWSsGrpPOL36oLAw/KWLuw/SW3TFn0NyQ6xYT+s0cBhu0nQPUNusNR4ow/SaeA0JRFzy9QQFJ+wReFsnf5l9aWnwIWl6VljSKEdsf6cXmk/bXly9QoRtSIMvRbSNwaYV30aG7md+XEXfGvl3bX5L9KLnvMuG3BPq5OvjDocOtAEYwN/ngr6UVNr16sezFfbeouLkFtu2wSkYmtTxac5/D7Ee2lszulNC5NIP090dQdSXOJqTexqbHcEctJ24f9CtHB1Y7b0vVjY1X2DsyknFTs4jHfwARmJfReWI/1pTmGzSLVyYBl03VPRlTApNqYiCONW6WzeOW6a/ci3CE7NP4j7GOKedWG/mg1bTLWkFwaB3J0P1yhfFet57KxurgIqSKyzKKNOTwam120vVgFivNoT0WL0dXEoz1rN9GE= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001); SRVR:BY1PR0701MB1721; BCL:0; PCL:0; RULEID:; SRVR:BY1PR0701MB1721; X-Microsoft-Exchange-Diagnostics: 1; BY1PR0701MB1721; 4:qNEujxKq/W237nzqzkB4nS3KIEqifR5xWiiR+mvzop2qLjdbVwoPEzUEFkqmx8r2IRNSGz/Czo+ENkXRXv6gFfD38+v00XGhtbtGmnB5XHCTgTOipIWyCaxkMbWY7CuB4A0d3QxstHW/LthZxf/7ck/gWUv9RaWRNXSkuPebk8LbrMqb0eaqwhgg2MtmvPP5DoNEdBM7gNkEWMxL1cJymZa4pwVilGvUjxYydAjdNmdPXqpoG+1lvlMmaY8740VUw5ZZppFKoew6zGhUQK7E6Der64Oa4MGsLh+Vk3y5r6COIcDyTJ/uTpeNRJI8AjAiq3FKtqMaUTTzYm6SuBXm0KwCx38JlUjVDDIdgMHdTL7VrBLvFigu3VqsVIG+iF+0 X-Forefront-PRVS: 0850800A29 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(6069001)(42186005)(50226001)(4326007)(36756003)(2906002)(586003)(3846002)(1096002)(47776003)(40100003)(122386002)(6116002)(76176999)(92566002)(5004730100002)(50466002)(4001430100002)(2351001)(19580395003)(2950100001)(86362001)(575784001)(87976001)(5003940100001)(229853001)(33646002)(110136002)(19580405001)(50986999)(189998001)(48376002)(66066001)(77096005)(5008740100001)(107886002)(5001960100002)(7099028); DIR:OUT; SFP:1101; SCL:1; SRVR:BY1PR0701MB1721; H:localhost.localdomain.localdomain; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY1PR0701MB1721; 23:9BUrM0OfSH6ustEbqSEpn9WiIl92UKbRtxmahnx?= =?us-ascii?Q?iVGGsH7s+Z1ks3uyBGF3gEhNi1ki5lp0cNUQfVma+JfsftzfmsqYeArj/sGB?= =?us-ascii?Q?acY0WWId0QuvrD9qYTGiHa9ShSwJp7YNu9LX4fcpy1pMfJgNRuTSg/VYQOgH?= =?us-ascii?Q?KwvHBOKeZoX2VJy9vjlTN2t9nUaP8Cbc5NW/k/KORPIr0IwekD2u4fd9sbKV?= =?us-ascii?Q?S84ceSdnHyHIK+XXPQfxLcIMqUeMSj14oYG21Lj7XCTT/rQM9YDwlXIbiBrW?= =?us-ascii?Q?Fnsl8QYlnRQ/36TRVYT8xI7bmr7axv2sBO5HC0/eqxDruH/vA4wllNs+ORX8?= =?us-ascii?Q?U2UXhMlK9dIl1Fb0iph5ZiolSXdX4NBs8ytq+3U6jzcNJONpZ7W51YWZzqZo?= =?us-ascii?Q?WE7QC5qVUEJT1DWHMR7AOU73aLWILyRwNRyFAgZxCUPUJdtSDbDuMdHByyrM?= =?us-ascii?Q?HwcMEdL0JQEvtbgofJe9bpTQz6JCU7baJbMramPY2AdE9yRXY8WgKKqyDxCL?= =?us-ascii?Q?bJpZZbQg8os0pRl0jyX7y/AbmEI+MgcQm1bcfBjjygbpoQprUpRcaxa7YCPA?= =?us-ascii?Q?3YOPOym96FKG3t9nUI0oNJq5wMAFlgfOYst3LA1zFthxkFdWwOQXCQMVsSdP?= =?us-ascii?Q?YTN2dNzO9sggj6G0vCwqoHvQObi48B0mMM6I38owem8a8VVzCXjWDu4SeFM4?= =?us-ascii?Q?o9oyhnE+JOebgcWkDQdEe+BGe5kXdM4FPB+Q0XfkWuSsOBIMkycnRo3SePly?= =?us-ascii?Q?iYxIQWnl8lENsEo3Og9DEz8znaFZ4lVM3oGth866f+sEMttGiKrv5O+ohyaj?= =?us-ascii?Q?lT9Ccirqry+p8sKosurrt+fCdc12L2LK8gmwSs2VVhKz6j+y4o4jPrG1e5Ye?= =?us-ascii?Q?XsdUJMNIVhobwUFqlN8SboqN/jNw4TyWfprDwC4Mm5eIzz5cco6n68HUhbs5?= =?us-ascii?Q?8h939PZSlfVc77BAn0KZ9VLzvsjl5BmM4y1LguV9QiMWMFOofdViJDPkUfuW?= =?us-ascii?Q?IM4AVkyoh7Rsp8e/geEGP16EQI0p2ky7ubuI9Sxqoman3q9HY2gRZiJjoOIv?= =?us-ascii?Q?z7ikjkZo=3D?= X-Microsoft-Exchange-Diagnostics: 1; BY1PR0701MB1721; 5:Q1/DSJ1QklOzZruJ7HKH7YBkWBCBohLW/sr5fEx8Teq8XE+Iqc6MxI6KxBCIwoQ4oUaZ1nUVzOZuDCfMOqFZgfKd5/1ZgCDSuvtwIPy19IME+FdpnnlCYmBY8LAflkMIZQD5CtNARYVZSFO7HMUiuw==; 24:BZZIF4PriQ41kLRY0smEewp9nb2ELR1LOZmL7sAnOFixemd/uyZScbqFMmuRW4kSPVmOP+aVGygUnufekZdW2BWUTOapzb9+doSZgbkWP+E= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Feb 2016 12:29:30.0558 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR0701MB1721 Cc: viktorin@rehivetech.com Subject: [dpdk-dev] [PATCH v4 2/3] lpm: add support for NEON X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Feb 2016 12:29:34 -0000 Enabled CONFIG_RTE_LIBRTE_LPM, CONFIG_RTE_LIBRTE_TABLE, CONFIG_RTE_LIBRTE_PIPELINE libraries for arm and arm64 TABLE, PIPELINE libraries were disabled due to LPM library dependency. Signed-off-by: Jerin Jacob Signed-off-by: Jianbo Liu --- app/test/test_xmmt_ops.h | 20 ++++ config/defconfig_arm-armv7a-linuxapp-gcc | 3 - config/defconfig_arm64-armv8a-linuxapp-gcc | 3 - lib/librte_lpm/Makefile | 4 + lib/librte_lpm/rte_lpm.h | 4 + lib/librte_lpm/rte_lpm_neon.h | 148 +++++++++++++++++++++++++++++ 6 files changed, 176 insertions(+), 6 deletions(-) create mode 100644 lib/librte_lpm/rte_lpm_neon.h diff --git a/app/test/test_xmmt_ops.h b/app/test/test_xmmt_ops.h index c055912..de9c16f 100644 --- a/app/test/test_xmmt_ops.h +++ b/app/test/test_xmmt_ops.h @@ -36,6 +36,24 @@ #include +#if defined(RTE_ARCH_ARM) || defined(RTE_ARCH_ARM64) + +/* vect_* abstraction implementation using NEON */ + +/* loads the xmm_t value from address p(does not need to be 16-byte aligned)*/ +#define vect_loadu_sil128(p) vld1q_s32((const int32_t *)p) + +/* sets the 4 signed 32-bit integer values and returns the xmm_t variable */ +static inline xmm_t __attribute__((always_inline)) +vect_set_epi32(int i3, int i2, int i1, int i0) +{ + int32_t data[4] = {i0, i1, i2, i3}; + + return vld1q_s32(data); +} + +#elif defined(RTE_ARCH_X86) + /* vect_* abstraction implementation using SSE */ /* loads the xmm_t value from address p(does not need to be 16-byte aligned)*/ @@ -44,4 +62,6 @@ /* sets the 4 signed 32-bit integer values and returns the xmm_t variable */ #define vect_set_epi32(i3, i2, i1, i0) _mm_set_epi32(i3, i2, i1, i0) +#endif + #endif /* _TEST_XMMT_OPS_H_ */ diff --git a/config/defconfig_arm-armv7a-linuxapp-gcc b/config/defconfig_arm-armv7a-linuxapp-gcc index cbebd64..efffa1f 100644 --- a/config/defconfig_arm-armv7a-linuxapp-gcc +++ b/config/defconfig_arm-armv7a-linuxapp-gcc @@ -53,9 +53,6 @@ CONFIG_RTE_LIBRTE_KNI=n CONFIG_RTE_EAL_IGB_UIO=n # fails to compile on ARM -CONFIG_RTE_LIBRTE_LPM=n -CONFIG_RTE_LIBRTE_TABLE=n -CONFIG_RTE_LIBRTE_PIPELINE=n CONFIG_RTE_SCHED_VECTOR=n # cannot use those on ARM diff --git a/config/defconfig_arm64-armv8a-linuxapp-gcc b/config/defconfig_arm64-armv8a-linuxapp-gcc index eacd01c..52e0c97 100644 --- a/config/defconfig_arm64-armv8a-linuxapp-gcc +++ b/config/defconfig_arm64-armv8a-linuxapp-gcc @@ -49,7 +49,4 @@ CONFIG_RTE_LIBRTE_IVSHMEM=n CONFIG_RTE_LIBRTE_FM10K_PMD=n CONFIG_RTE_LIBRTE_I40E_PMD=n -CONFIG_RTE_LIBRTE_LPM=n -CONFIG_RTE_LIBRTE_TABLE=n -CONFIG_RTE_LIBRTE_PIPELINE=n CONFIG_RTE_SCHED_VECTOR=n diff --git a/lib/librte_lpm/Makefile b/lib/librte_lpm/Makefile index ce3a1d1..656ade2 100644 --- a/lib/librte_lpm/Makefile +++ b/lib/librte_lpm/Makefile @@ -47,7 +47,11 @@ SRCS-$(CONFIG_RTE_LIBRTE_LPM) := rte_lpm.c rte_lpm6.c # install this header file SYMLINK-$(CONFIG_RTE_LIBRTE_LPM)-include := rte_lpm.h rte_lpm6.h +ifneq ($(filter y,$(CONFIG_RTE_ARCH_ARM) $(CONFIG_RTE_ARCH_ARM64)),) +SYMLINK-$(CONFIG_RTE_LIBRTE_LPM)-include += rte_lpm_neon.h +else ifeq ($(CONFIG_RTE_ARCH_X86),y) SYMLINK-$(CONFIG_RTE_LIBRTE_LPM)-include += rte_lpm_sse.h +endif # this lib needs eal DEPDIRS-$(CONFIG_RTE_LIBRTE_LPM) += lib/librte_eal diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h index dfe1378..2c34a25 100644 --- a/lib/librte_lpm/rte_lpm.h +++ b/lib/librte_lpm/rte_lpm.h @@ -384,7 +384,11 @@ static inline void rte_lpm_lookupx4(const struct rte_lpm *lpm, xmm_t ip, uint16_t hop[4], uint16_t defv); +#if defined(RTE_ARCH_ARM) || defined(RTE_ARCH_ARM64) +#include "rte_lpm_neon.h" +#elif defined(RTE_ARCH_X86) #include "rte_lpm_sse.h" +#endif #ifdef __cplusplus } diff --git a/lib/librte_lpm/rte_lpm_neon.h b/lib/librte_lpm/rte_lpm_neon.h new file mode 100644 index 0000000..fcd2a8a --- /dev/null +++ b/lib/librte_lpm/rte_lpm_neon.h @@ -0,0 +1,148 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2015 Cavium Networks. All rights reserved. + * All rights reserved. + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Derived rte_lpm_lookupx4 implementation from lib/librte_lpm/rte_lpm_sse.h + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Cavium Networks nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTE_LPM_NEON_H_ +#define _RTE_LPM_NEON_H_ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void +rte_lpm_lookupx4(const struct rte_lpm *lpm, xmm_t ip, uint16_t hop[4], + uint16_t defv) +{ + uint32x4_t i24; + rte_xmm_t i8; + uint16_t tbl[4]; + uint64_t idx, pt; + + const uint32_t mask = UINT8_MAX; + const int32x4_t mask8 = vdupq_n_s32(mask); + + /* + * RTE_LPM_VALID_EXT_ENTRY_BITMASK for 4 LPM entries + * as one 64-bit value (0x0300030003000300). + */ + const uint64_t mask_xv = + ((uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK | + (uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK << 16 | + (uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK << 32 | + (uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK << 48); + + /* + * RTE_LPM_LOOKUP_SUCCESS for 4 LPM entries + * as one 64-bit value (0x0100010001000100). + */ + const uint64_t mask_v = + ((uint64_t)RTE_LPM_LOOKUP_SUCCESS | + (uint64_t)RTE_LPM_LOOKUP_SUCCESS << 16 | + (uint64_t)RTE_LPM_LOOKUP_SUCCESS << 32 | + (uint64_t)RTE_LPM_LOOKUP_SUCCESS << 48); + + /* 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); + + tbl[0] = *(const uint16_t *)&lpm->tbl24[(uint32_t)idx]; + tbl[1] = *(const uint16_t *)&lpm->tbl24[idx >> 32]; + + idx = vgetq_lane_u64((uint64x2_t)i24, 1); + + tbl[2] = *(const uint16_t *)&lpm->tbl24[(uint32_t)idx]; + tbl[3] = *(const uint16_t *)&lpm->tbl24[idx >> 32]; + + /* get 4 indexes for tbl8[]. */ + i8.x = vandq_s32(ip, mask8); + + pt = (uint64_t)tbl[0] | + (uint64_t)tbl[1] << 16 | + (uint64_t)tbl[2] << 32 | + (uint64_t)tbl[3] << 48; + + /* search successfully finished for all 4 IP addresses. */ + if (likely((pt & mask_xv) == mask_v)) { + uintptr_t ph = (uintptr_t)hop; + *(uint64_t *)ph = pt & 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] + + (uint8_t)tbl[0] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES; + tbl[0] = *(const uint16_t *)&lpm->tbl8[i8.u32[0]]; + } + if (unlikely((pt >> 16 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) == + RTE_LPM_VALID_EXT_ENTRY_BITMASK)) { + i8.u32[1] = i8.u32[1] + + (uint8_t)tbl[1] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES; + tbl[1] = *(const uint16_t *)&lpm->tbl8[i8.u32[1]]; + } + if (unlikely((pt >> 32 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) == + RTE_LPM_VALID_EXT_ENTRY_BITMASK)) { + i8.u32[2] = i8.u32[2] + + (uint8_t)tbl[2] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES; + tbl[2] = *(const uint16_t *)&lpm->tbl8[i8.u32[2]]; + } + if (unlikely((pt >> 48 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) == + RTE_LPM_VALID_EXT_ENTRY_BITMASK)) { + i8.u32[3] = i8.u32[3] + + (uint8_t)tbl[3] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES; + tbl[3] = *(const uint16_t *)&lpm->tbl8[i8.u32[3]]; + } + + hop[0] = (tbl[0] & RTE_LPM_LOOKUP_SUCCESS) ? (uint8_t)tbl[0] : defv; + hop[1] = (tbl[1] & RTE_LPM_LOOKUP_SUCCESS) ? (uint8_t)tbl[1] : defv; + hop[2] = (tbl[2] & RTE_LPM_LOOKUP_SUCCESS) ? (uint8_t)tbl[2] : defv; + hop[3] = (tbl[3] & RTE_LPM_LOOKUP_SUCCESS) ? (uint8_t)tbl[3] : defv; +} + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_LPM_NEON_H_ */ -- 2.1.0